Python 2.6 GC появляется для очистки объектов, но память не освобождается - PullRequest
3 голосов
/ 09 февраля 2011

У меня есть программа, написанная на python 2.6, которая создает большое количество кратковременных экземпляров (это классическая проблема производитель-потребитель).Я заметил, что использование памяти, сообщаемое top и pmap, кажется, увеличивается при создании этих экземпляров и никогда не возвращается обратно.Я был обеспокоен тем, что какой-то модуль Python, который я использовал, мог пропускать память, поэтому я тщательно изолировал проблему в своем коде.Затем я продолжил воспроизводить его как можно более кратким примером.Я придумал это:

class LeaksMemory(list):
    timesDelCalled = 0

    def __del__(self):
        LeaksMemory.timesDelCalled +=1


def leakSomeMemory():
    l = []
    for i in range(0,500000):
        ml = LeaksMemory()
        ml.append(float(i))
        ml.append(float(i*2))
        ml.append(float(i*3))
        l.append(ml)

import gc
import os


leakSomeMemory()

print("__del__ was called " + str(LeaksMemory.timesDelCalled) + " times")
print(str(gc.collect())  +" objects collected")
print("__del__ was called " + str(LeaksMemory.timesDelCalled) + " times")
print(str(os.getpid()) + " : check memory usage with pmap or top")

Если вы запустите это с чем-то вроде 'python2.6 -i memoryleak.py', оно остановится, и вы можете использовать pmap -x PID для проверки использования памяти.Я добавил метод del , чтобы убедиться, что GC происходит.Его нет в моей реальной программе и, похоже, не имеет никакого функционального значения.Каждый вызов leakSomeMemory () увеличивает объем памяти, используемой этой программой.Боюсь, что я делаю какую-то простую ошибку, и ссылки хранятся случайно, но не могу ее идентифицировать.

Ответы [ 2 ]

8 голосов
/ 09 февраля 2011

Python освобождает объекты, но не сразу возвращает память операционной системе. Вместо этого он будет повторно использовать те же сегменты для будущих распределений в том же интерпретаторе.

Вот сообщение в блоге о проблеме: http://effbot.org/pyfaq/why-doesnt-python-release-the-memory-when-i-delete-a-large-object.htm

ОБНОВЛЕНИЕ: Я сам протестировал это на Python 2.6.4 и не заметил постоянного увеличения использования памяти. Некоторые вызовы leakSomeMemory() вызывали увеличение объема памяти процесса Python, а некоторые заставляли его снова уменьшаться. Так что все зависит от того, как распределитель повторно использует память.

4 голосов
/ 09 февраля 2011

Согласно Алексу Мартелли :

"Единственный действительно надежный способ гарантировать, что большое, но временное использование памяти возвращает все ресурсы системе после ее завершения,чтобы такое использование происходило в подпроцессе, который завершает работу, требующую памяти, а затем завершается.Модуль 1010 * для запуска недолговечных функций в отдельных процессах для обеспечения возврата ресурсов после завершения процесса.

import multiprocessing as mp

def NOT_leakSomeMemory():
    # do stuff
    return result


if __name__=='__main__':
    pool = mp.Pool()
    results=pool.map(NOT_leakSomeMemory, range(500000)) 

Дополнительные сведения о настройке с помощью многопроцессорной обработки см. В DougУчебник Хеллмана :

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...