编辑:更新
我使用objgraph
为内存泄漏中出现的'Reference'
项打印back reference graphs。似乎PdfPages保留了所有图像,因为我遍历它们并将它们保存到每个页面(因此也许是PdfPages模块固有的东西)。我想我将修改我的代码,在每次迭代时编写一个小的PDF文件,然后使用pypdf
将这些文件合并到我想要的更大的PDF文件中。
编辑:我正在使用Matplotlib 1.3.1运行Python 2.7.3。我已经尝试打印出gc.garbage
,但这会返回一个空列表,因此看起来没有任何无法收集的对象。我也尝试过使用PDF和Agg后端,但内存泄漏仍然存在于这两种情况中。我尝试专门关闭轴(ax1
和cbaxes1
)并在所有变量上明确使用del
(在关闭后删除+3列表但增加+2的效果保存到+5列表后的列表。
我正在尝试通过pcolormesh创建多个热图并将它们保存到PDF中的单个页面并重复此过程以在PDF文件中创建带有图形的多个页面(我已将其下拉到每页只有一个数字这个例子的缘故)。
savefig函数似乎发生了内存泄漏,起初看起来很小,但实际上是因为我希望能够保存非常大的PDF文件。
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib import gridspec
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import numpy as np
import resource
import gc
import objgraph
def plotfunction(i,pdf):
fig = plt.figure()
fig.set_figheight(25)
fig.set_figwidth(64)
gs = gridspec.GridSpec(1,2)
ax1 = plt.subplot(gs[0],rasterized=True)
heatmap1 = ax1.pcolormesh(np.random.uniform(size=(10,10)))
cbaxes1 = plt.subplot(gs[1],rasterized=True)
cb1 = plt.colorbar(heatmap1, cax= cbaxes1, use_gridspec = True)
gc.collect()
print 'Memory Growth before savefig {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
objgraph.show_growth()
pdf.savefig(fig) # the memory leak seems to occur here
gc.collect()
print 'Memory Growth after savefig {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
objgraph.show_growth()
fig.clf()
plt.close(fig)
plt.close('all')
gc.collect()
print 'Memory Growth after closing {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
objgraph.show_growth()
def main():
pdf = PdfPages('output.pdf')
for i in range(15):
plotfunction(i,pdf)
print 'Memory Growth outside function {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
gc.collect()
objgraph.show_growth()
pdf.close()
if __name__ == "__main__":
main()
这是显示内存泄漏的输出:
Memory Growth before savefig 7: 877674496 (837 MB)
Memory Growth after savefig 7: 988385280 (942 MB)
Reference 32 +3
list 1839 +2
Name 16 +2
tuple 2384 +2
Memory Growth after closing 7: 988385280 (942 MB)
list 1842 +3
Memory Growth outside function 7: 988385280 (942 MB)
Memory Growth before savefig 8: 988651520 (942 MB)
Memory Growth after savefig 8: 1099231232 (1048 MB)
Reference 35 +3
list 1844 +2
Name 18 +2
tuple 2386 +2
Memory Growth after closing 8: 1099231232 (1048 MB)
list 1847 +3
Memory Growth outside function 8: 1099231232 (1048 MB)
我尝试过使用多处理,避免pyplot,并将保存移动到其他帖子中建议的其他功能,但这些解决方案都没有解决内存泄漏问题。
感谢。