Потребление памяти Python в Linux: физическая и виртуальная память растут, а размер кучи остается прежним
Я работаю над каким-то системным сервисом (на самом деле это просто парсер журналов), написанным на Python. Эта программа должна работать непрерывно в течение длительного времени (надеюсь, я имею в виду дни и недели без сбоев и необходимости перезапуска). Вот почему меня беспокоит потребление памяти.
Я собрал разную информацию об использовании памяти процесса с разных сайтов в одну простую функцию:
#!/usr/bin/env python
from pprint import pprint
from guppy import hpy
from datetime import datetime
import sys
import os
import resource
import re
def debug_memory_leak():
#Getting virtual memory size
pid = os.getpid()
with open(os.path.join("/proc", str(pid), "status")) as f:
lines = f.readlines()
_vmsize = [l for l in lines if l.startswith("VmSize")][0]
vmsize = int(_vmsize.split()[1])
#Getting physical memory size
pmsize = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
#Analyzing the dynamical memory segment - total number of objects in memory and heap size
h = hpy().heap()
if __debug__:
print str(h)
m = re.match(
"Partition of a set of ([0-9]+) objects. Total size = ([0-9]+) bytes(.*)", str(h))
objects = m.group(1)
heap = int(m.group(2))/1024 #to Kb
current_time = datetime.now().strftime("%H:%M:%S")
data = (current_time, objects, heap, pmsize, vmsize)
print("\t".join([str(d) for d in data]))
Эта функция использовалась, чтобы изучить динамику потребления памяти моего долгоиграющего процесса, и я до сих пор не могу объяснить его поведение. Вы можете видеть, что размер кучи и общее количество объектов не изменились, в то время как физическая и виртуальная память увеличились на 11% и 1% за эти двадцать минут.
UPD: к этому моменту процесс работал почти 15 часов. Куча все та же, но физическая память увеличилась в шесть раз, а виртуальная память увеличилась на 50%. Кривая кажется линейной, за исключением странных выбросов в 3:00 утра:
Time Obj Heap PhM VM
19:04:19 31424 3928 5460 143732
19:04:29 30582 3704 10276 158240
19:04:39 30582 3704 10372 157772
19:04:50 30582 3709 10372 157772
19:05:00 30582 3704 10372 157772
(...)
19:25:00 30583 3704 11524 159900
09:53:23 30581 3704 62380 210756
Интересно, что происходит с адресным пространством моего процесса. Постоянный размер кучи говорит о том, что все динамические объекты освобождены правильно. Но я не сомневаюсь, что растущее потребление памяти повлияет на устойчивость этого жизненно важного процесса в долгосрочной перспективе.
Может кто-нибудь прояснить этот вопрос, пожалуйста? Спасибо.
(Я использую RHEL 6.4, ядро 2.6.32-358 с Python 2.6.6)
1 ответ
Не зная, что делает ваша программа, это может помочь.
Я сталкивался с этой статьей, когда некоторое время назад работал над проектом: http://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html котором говорится: "Долго работающий Python задания, которые занимают много памяти во время работы, могут не вернуть эту память операционной системе до тех пор, пока процесс не прекратится, даже если все правильно собрано для сбора мусора ".
Я закончил тем, что использовал многопроцессорный модуль, чтобы мой проект разветвлялся как отдельный процесс и возвращался, когда это было необходимо для работы, и с тех пор я не заметил никаких проблем с памятью.
Это или попробуйте в Python 3.3 http://bugs.python.org/issue11849