У меня есть сценарий, который я использую для создания файла Sitemap. Для каждой из соответствующих моделей я создаю несколько постраничных карточек с URL для каждого объекта, и каждый неделю Я намерен снова запустить сценарий, чтобы восстановить карту сайта со свежими данными.Видимая утечка памяти в скрипте Python с использованием Django
Однако, когда я запускаю этот скрипт на своем сервере Ubuntu, использование памяти продолжает расти, пока процесс не будет уничтожен ОС. Вот функция, я в настоящее время возникают проблемы при получении через:
def xml_for_page(object):
sOutText = "\t<url>\n"
sURL = object.url()
sOutText += "\t\t<loc>http://www.mysite.com%s</loc>\n" % sURL
sLastModified = object.last_status_change.isoformat()
sOutText += "\t\t<lastmod>%s</lastmod>\n" % sLastModified
sChangeFreq = "monthly"
sOutText += "\t\t<changefreq>%s</changefreq>\n" % sChangeFreq
sOutText += "\t</url>\n"
return sOutText
def generate_object_map():
# Do this in chunks of ITEMS_PER_FILE
bFinished = False
iOffset = 0
iCurrentPage = 0
while not bFinished:
objResults = PageObject.objects.filter(submission_status=SUBMISSION_STATUS_ACCEPTED).order_by('-popularity')[iOffset:iOffset+ITEMS_PER_FILE]
if objResults.count() < 1:
break
sFilename = "%s/sitemap-objects-%i.xml" % (OUTPUT_DIR, iCurrentPage)
fObjects = open(sFilename, 'w')
fObjects.write('<?xml version="1.0" encoding="UTF-8"?>\n')
fObjects.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n')
for object in objResults:
fObjects.write(xml_for_page(object))
fObjects.write('</urlset>')
fObjects.close()
iOffset += ITEMS_PER_FILE
iCurrentPage += 1
Так что же здесь происходит: при каждой итерации цикла while not bFinished
мы создаем новый файл для страницы, мы на, и запрос к базе данных для этот конкретный набор объектов. Затем мы перебираем эти объекты и записываем XML для этой страницы в файл Sitemap. Как только они написаны, мы закрываем этот файл и запускаем другой. Причиной этого поведения подкачки является то, что при записи всех записей в один файл я быстро ударяю по памяти. Это ведет себя лучше, чем это было тогда, но когда я использую resource
для отслеживания использования памяти, я вижу, как он поднимается после каждого записанного файла. В базе данных около 200 000 объектов этого типа, поэтому в идеале мне нужно сделать это максимально масштабируемым. Однако я не вижу, как память хранится после каждой итерации основного цикла: объект QuerySet
переписывается после каждой итерации, а дескриптор файла закрывается и перераспределяется после каждой итерации. Я думал, что поведение GC на Python позволит очищать ненужные объекты после того, как переменная была перераспределена. Разве это не так?
Может ли 'object.url()' что-то делать? Что делать, если вы заменили модели django только набором строк и вместо этого написали это в файл, чтобы увидеть, имеет ли это модели или ваша «xml_for_page». Продолжайте сокращать примерный код, это то, что я говорю – TankorSmash
Если вы собираетесь использовать масштабируемость, почему бы не использовать в своих моделях '.defer' или' .only' или даже '.values_list'? Чем меньше количество звонков, тем лучше. – TankorSmash
Функция 'url()' - это то, что меня ограничивает здесь, - хотя я мог бы получить идентификатор и 'last_modified_date' через' values_list', функция 'url' использует значения из полей внешнего ключа, поэтому мне все равно придется извлекать объект сам. Или существует аналогичная функция для получения результатов одной конкретной функции-члена? – benwad