Подтвердить что ты не робот

Сбор мусора Python

Я создал некоторый код python, который создает объект в цикле, и на каждой итерации он перезаписывает этот объект новым одним и тем же типом. Это делается 10 000 раз, а Python занимает 7 МБ памяти каждую секунду, пока не будет использована моя 3-гигабайтная ОЗУ. Кто-нибудь знает, как удалить объекты из памяти?

4b9b3361

Ответ 1

Вы не предоставили достаточно информации - это зависит от специфики создаваемого объекта и того, что еще вы делаете с ним в цикле. Если объект не создает циклические ссылки, он должен быть освобожден на следующей итерации. Например, код

for x in range(100000):
  obj = " " * 10000000

не приведет к постоянно увеличивающемуся распределению памяти.

Ответ 2

Я думаю, что это круговая ссылка (хотя вопрос не является явным об этой информации.)

Одним из способов решения этой проблемы является ручное обращение к сборке мусора. Когда вы вручную запускаете сборщик мусора, он также будет перемещать объекты с круглыми ссылками.

import gc

for i in xrange(10000):
    j = myObj()
    processObj(j)
    #assuming count reference is not zero but still
    #object won't remain usable after the iteration

    if !(i%100):
        gc.collect()

Здесь не слишком часто запускается сборщик мусора, поскольку он имеет свои собственные служебные данные, например. если вы запускаете сборщик мусора в каждом цикле, интерпретация будет очень медленной.

Ответ 3

Это старая ошибка, которая была исправлена ​​для некоторых типов в python 2.5. Случилось то, что python не был так хорош в сборе таких вещей, как пустые списки/словари/tupes/floats/ints. В python 2.5 это было исправлено... в основном. Однако float и ints являются синглтонами для сравнений, поэтому, когда один из них создается, он остается вокруг до тех пор, пока интерпретатор жив. Я был укушен этим худшим, имея дело с большим количеством поплавков, так как у них неприятная привычка быть уникальной. Это было охарактеризовано для python 2.4 и обновлено о том, что оно складывается в python 2.5

Лучшим способом, который я нашел вокруг него, является обновление до python 2.5 или новее, чтобы заботиться о проблемах с списками/словарями/кортежами. Для чисел единственным решением является не допускать попадания больших чисел чисел в питон. Я сделал это с моей собственной оболочкой для объекта С++, но у меня сложилось впечатление, что numpy.array даст похожие результаты.

Как сообщение script Я понятия не имею, что с этим произошло в python 3, но я подозрительно, что числа все еще являются частью одноэлементного. Таким образом, утечка памяти на самом деле является признаком языка.

Ответ 4

Если вы создаете циклические ссылки, ваши объекты не будут освобождены немедленно, но придется ждать выполнения цикла GC.

Вы можете использовать модуль weakref для решения этой проблемы или явно использовать объекты после использования.

Ответ 5

Я обнаружил, что в моем случае (с Python 2.5.1), с круговыми ссылками, включающими классы с методами __del__(), не только сбор мусора не происходил своевременно, методы __del__() моих объектов были никогда не вызывается, даже когда script вышел. Поэтому я использовал weakref, чтобы разбить круговые ссылки, и все было хорошо.

Престижность Майлза, который предоставил всю информацию в своих комментариях для меня, чтобы собрать это вместе.

Ответ 6

Здесь одна вещь, которую вы можете сделать в REPL, чтобы вызвать разыменование переменной:

>>> x = 5
>>> x
5
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined