Принудительно отбрасывать изображения библиотеки изображений Python для восстановления памяти - PullRequest
4 голосов
/ 29 декабря 2011

У меня есть программа, которая загружает и обрабатывает много изображений этой формы:

for fn in filenames:
    im = Image.open(fn)
    get_some_basic_stats(im)

При запуске на многих изображениях процесс Python заканчивается использованием большого объема памяти - гораздо больше, чем любое одно изображение должно учитывать. Излишне говорить, что это в конечном итоге приводит к уничтожению файла подкачки.

Полагаю (хотя я не уверен на 100%, очевидно), это потому, что предыдущие изображения занимают память до тех пор, пока не будут собраны в мусор.

Есть ли способ принудительно отказаться от них? Мне не удалось найти его в справочнике PIL . Я думал об использовании del im, но я понял, что это просто удалит имя 'im' из локальной области видимости и будет фактически таким же, как и переназначение его в верхней части цикла.

1 Ответ

3 голосов
/ 29 декабря 2011

Ничто в python не может явно уничтожено. В CPython все ссылки подсчитываются, поэтому их следует освобождать, как только на них ничего не ссылается. В вашем случае это должно произойти в следующей итерации цикла. Вы можете принудительно запустить циклический сборщик мусора, запустив gc.collect(), но я сомневаюсь, что это решит проблему здесь.

Вы можете попробовать: print sys.getrefcount(im) в конце цикла. Он скажет вам, сколько объектов ссылаются на изображение. Должно быть 2 (один для локальной переменной, один для im в качестве параметра getrefcount). Если оно больше, это объясняет, почему объект не был освобожден.

Вы также можете посмотреть на gc.getobjects(), который вернет список всех объектов в системе python. Я написал бы быстрый цикл, который подсчитывает объекты разных типов и печатает их. Посмотрим, увеличится ли счет на что-либо.

...