EDIT: решаемыеxPython savefig утечка памяти нерешенным с ранее предлагаемыми решениями
Но я не знаю, как ... я переехал столько, сколько я мог pylab вместо pyplot, реализован многопроцессорная подход, описанный [здесь] [1], и в этот момент он работал нормально. Затем, пытаясь определить проблему, я пошагово менял код. Но он продолжал работать, даже без многопроцессорности, даже с помощью pyplot и т. Д. Только когда я снимаю fig.clf(), теперь это не сработает, что, по-видимому, испытывает большинство людей, но изначально это не было проблемой. Ну, возможно, это было, может быть, заявление clf() не было в нужном месте или что-то в этом роде. Благодаря !
EDIT: ПРОБЛЕМА НЕ РЕШИТЬ ЕЩЕ
Это очень удивительно. Теперь я переместил мою функцию savefig() во внешний модуль, который я импортирую при выполнении моего скрипта. Вот функция:
def savethefig(fig,outpath,luname):
plt.savefig(outpath+luname+'testredtarget.png',dpi=500)
Так что теперь я сделать что-то вроде:
from myfile import savethefig
fig = plt.figure()
ax1 = fig.add_subplot(311)
pftmap=zeros(shape=(1800,3600))*nan
for i in range(len(pftspatialnames)):
pftmap[indlat,indlon]=data[i,:]
fig = pylab.gcf()
a1=ax1.imshow(pftmap, interpolation='nearest',origin='upper', aspect='auto')
savethefig(fig,outpath,luname)
Я сделал все шаг за шагом, строка за строкой и ОЗУ определенно идет вверх, когда hiting функцию savefig() внутри внешняя функция. Подходит примерно на 500 МБ. Затем, возвращаясь к основному скрипту, эта память не будет выпущена. Разве внешняя функция не должна очищать все? Я что-то не хватает ...
ОРИГИНАЛЬНЫЙ ПОСТ:
Я использую питона EDP 7.3-2 (32 бит) (Python 2.7.3).
У меня есть программа, которая выполняет некоторые вычисления, затем отображает некоторые результаты и сохраняет изображения с помощью matplotlib.
Это довольно большой объем данных, и если я попытаюсь отобразить и сохранить слишком много изображений, я попал в пределы памяти. Который я не должен с тех пор, как повторно использовать ту же фигуру, и не создаю новых переменных. Я некоторое время боролся с этим, пробовал все способы очистки/удаления и т. Д. Решений, меняя бэкэнд, используемый matplotlib, но ничего не делает, каждый раз, когда код попадает в функцию savefig, он добавляет много памяти и не принимает это позже.
Я далеко не эксперт на вещи памяти (или питона, кстати), но вот одна диагностирует попытка я побежал, используя модуль objgraph:
from numpy import *
import matplotlib
matplotlib.use('Agg')
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib import pyplot as plt
outpath = '/Users/yannick/Documents/outputs/'
pftspatialnames = ['forest','shrubs','grass']
Computations (not shown)
fig = plt.figure()
for i in range(len(pftspatialnames)):
pftmap=zeros(shape=(1800,3600))*nan
pftmap[indlat,indlon]=data[i,:]
fig = pylab.gcf()
ax1 = plt.subplot2grid((3,1),(0,0))
a1=ax1.imshow(pftmap, interpolation='nearest',origin='upper', aspect='auto')
del(pftmap)
gc.collect()
print 'MEMORY LEAK DETECTOR before figsave'
objgraph.show_growth()
plt.savefig(outpath+pftspatialnames[i]+'testredtarget.png', dpi=500)
print 'MEMORY LEAK DETECTOR after figsave'
objgraph.show_growth()
Довольно большие карты (и есть 3 из них, 3 подзаголовка, просто показали один здесь), но он справляется с этим довольно хорошо. Для насыщения памяти требуется около 4 цифр. Некоторые вещи могут быть излишними (например, удаление pftmap), но я пытался все очистить память.
А вот печатная продукция:
MEMORY LEAK DETECTOR before figsave
dict 6640 +2931
weakref 3218 +1678
instance 1440 +1118
tuple 3501 +939
function 12486 +915
Bbox 229 +229
instancemethod 684 +171
Line2D 147 +147
TransformedBbox 115 +115
Path 127 +114
MEMORY LEAK DETECTOR after figsave
dict 7188 +548
Path 422 +295
weakref 3494 +276
instance 1679 +239
tuple 3703 +202
function 12670 +184
TransformedPath 87 +87
instancemethod 741 +57
Line2D 201 +54
FontProperties 147 +36
Так перед вызовом savefig есть много новых объектов (это нормально я сделать кучу вещей в коде раньше). Но тогда, просто позвонив savefig, мы добавим 550 dict и т. Д. Может ли это быть источником моей проблемы? Обратите внимание, что это происходит при первом вызове savefig. Любой последующий вызов делает следующее:
MEMORY LEAK DETECTOR before figsave
MEMORY LEAK DETECTOR after figsave
tuple 3721 +6
dict 7206 +6
function 12679 +3
list 2001 +3
weakref 3503 +3
instance 1688 +3
Bbox 260 +3
но память все еще продолжает расти, и вскоре я нажму память.
Большое спасибо!
Что произойдет, если вы gc.collect() 'между savefigs? – rickhg12hs
Спасибо! Я фактически делаю gc.collect между фиг. –
Путь к коду в сохранении зависит от того, какие художники на вашем рисунке. Предоставьте полный (но минимальный) код, чтобы продемонстрировать проблему. – tacaswell