Я знаю, что у python есть своя собственная реализация управления памятью с использованием isans для объектов разного размера и многое другое, хотя я еще не нашел исчерпывающей документации. Еще я хотел бы понять, что происходит под капотом.Является ли python2 неохотой освобождать память?
Фон - это приложение для работы с базой данных python2, которое как-то кажется утечкой памяти, оно работает на 64-битном Linux. Каждый день это приложение считывает некоторые данные из БД, оно суммируется до ~ 3,5 ГБ использования ОЗУ только для чтения строк (с использованием MySQLdb). Есть около 3.5M строк, которые впоследствии уменьшаются до нескольких 100 строк, а остальная часть заканчивается («освобождена»).
Но python-2.7 освобождает только небольшую часть «неиспользуемой» памяти. Я уверен, что память будет повторно использована позже, но я заметил, что как-то эта память кажется «медленно течет». Указанное приложение БД читает этот огромный кусок данных каждый день. Чтение его дважды (или более раз) в строке выделяет только память для первого чтения, а затем, по-видимому, повторно использует эту память. Но позволяя ему работать в течение нескольких часов, а затем чтение данных БД снова создает следующий 3 + ГБ пик распределения памяти (который снова никогда не освобождается).
Чтобы добавить еще немного фона (и сделать что-то хуже для объяснения), я должен сказать, что это приложение БД не праздно, но постоянно выполняет задачи. Я уверен, что из-за мониторинга использования памяти (данных производительности nagios) использование памяти никогда не поднимается до 3,5 ГБ оперативной памяти (или даже близко) без этого конкретного запроса БД. Но с включением этого запроса каждый день добавляется 3 + ГБ оперативной памяти. Этот запрос возвращает в основном уникальные целые числа и поплавки.
Это основная причина, по которой я начал подозревать python в целом. Я чувствую, что прочитал тонны информации, посмотрел на _PyObject_DebugMallocStats(), но понятия не имею, что (или почему) python решает сохранить пару гигабайт.
Она сводится к очень простой пример (не представляя ситуацию в реальной жизни относительно данных, я знаю о xrange()):
def mem_usage(pid=None):
mem = 0
proc = str(pid or "self")
with open("/proc/%s/smaps" % proc) as fstat:
for l in fstat:
if not l.startswith("Private_"):
continue
mem += int(l.split(":", 1)[1].strip().split(" ", 1)[0])
return mem
mem_usage() # reports a few MB
x = list(range(100000000)) # use list() for py3k
mem_usage() # reports ~3GB
del x
mem_usage() # reports ~2.5GB
Что интересно, что py3k освобождает память, когда я удалить огромный список. Не только фракция, но и почти все, что позволяет использовать память только немного выше, чем в начале.
Я исследовал это с помощью memory_profiler (я думаю, это не делает намного больше, чем данная функция mem_usage()) без всякого понимания. Я читал о gdb-heap, но не смог заставить его работать до сих пор.
На самом деле я не считаю, что есть решение (кроме перезапуска приложения или уменьшения количества данных, считываемых из БД). Но я бы очень благодарен за понимание этой темы.
EDIT:
Резюмируя мой вопрос: Почему Питон-2,7 держать эту память, выделенную?
Итак, я прочитал вашу стену здесь, и я изо всех сил стараюсь найти вопрос ... Что именно вы спрашиваете? Вы говорите, что python не освобождает память, но python3k делает ... что вы ищете? Можете ли вы резюмировать четкий ответный вопрос? – mgilson
Я добавил вопрос как можно скорее :) – resi
@resi Мы pythonista. Можете ли вы задать вопрос в одном лайнере? Я понял, почему python 2 не освобождает память. – thefourtheye