Потребление памяти 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 ВМ

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)


person Vitaly Isaev    schedule 29.04.2014    source источник
comment
Как выглядит график, если вы бежите несколько часов вместо 20 минут?   -  person 2rs2ts    schedule 29.04.2014
comment
О, возможно, связано: stackoverflow.com/q/1194416/691859   -  person 2rs2ts    schedule 29.04.2014
comment
@ 2rs2ts, спасибо за ответ. График обновлю завтра, когда приду на работу :)   -  person Vitaly Isaev    schedule 29.04.2014
comment
@ 2rs2ts, процесс всю ночь работал, память все равно растет.   -  person Vitaly Isaev    schedule 30.04.2014
comment
Хорошо, это говорит о другом, чем просто несколько минут, так что спасибо за то, что измерили это и поделились. В любом случае, я не уверен, применимо ли это, но я видел этот вопрос программистам (сейчас он перенесен на SO) об использовании виртуальной памяти в простой java-программе Hello World. Постоянство размера кучи говорит мне, что вам не о чем беспокоиться, но беспокойство об увеличении физической памяти говорит об обратном. Я надеюсь, что кто-то еще может дать окончательный ответ.   -  person 2rs2ts    schedule 30.04.2014
comment
Возможно, стек неуклонно увеличивается, а вы об этом не догадываетесь? (Я не уверен, что этот вопрос вообще применим в данном случае, но ...) Вы можете взглянуть на стек, используя этот пример, так что, возможно, вы могли бы записать количество строк в отформатированном стеке и посмотреть, увеличивается ли оно.   -  person 2rs2ts    schedule 30.04.2014
comment
Фрагментируется ли пространство памяти Python или он просто никогда не освобождает память?   -  person benjimin    schedule 10.02.2018


Ответы (1)


Это может помочь, не зная, что делает ваша программа.

Некоторое время назад я наткнулся на эту статью, когда работал над проектом: http://chase-seibert.github.io/blog/2013/08/03/diagnosing-memory-leaks-python.html В нем говорится: «Долгосрочные задания Python, которые потребляют много ресурсов. памяти во время работы может не вернуть эту память в операционную систему до тех пор, пока процесс не завершится, даже если все правильно собрано мусором ».

Я закончил тем, что использовал модуль multiprocessing, чтобы мой проект создавал отдельный процесс и возвращался, когда ему нужно было работать, и с тех пор я не заметил никаких проблем с памятью.

Это или попробуйте в Python 3.3 http://bugs.python.org/issue11849

person user3588162    schedule 01.05.2014
comment
К сожалению, библиотека, которую я использую (auparse - идет с auditd в Linux), до сих пор не перенесена в третью ветвь. - person Vitaly Isaev; 25.06.2014