Matplotlib中的内存泄漏使用PDFPages保存图

时间:2014-06-01 17:53:14

标签: python python-2.7 memory-leaks matplotlib

编辑:更新

我使用objgraph为内存泄漏中出现的'Reference'项打印back reference graphs。似乎PdfPages保留了所有图像,因为我遍历它们并将它们保存到每个页面(因此也许是PdfPages模块固有的东西)。我想我将修改我的代码,在每次迭代时编写一个小的PDF文件,然后使用pypdf将这些文件合并到我想要的更大的PDF文件中。

编辑:我正在使用Matplotlib 1.3.1运行Python 2.7.3。我已经尝试打印出gc.garbage,但这会返回一个空列表,因此看起来没有任何无法收集的对象。我也尝试过使用PDF和Agg后端,但内存泄漏仍然存在于这两种情况中。我尝试专门关闭轴(ax1cbaxes1)并在所有变量上明确使用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,并将保存移动到其他帖子中建议的其他功能,但这些解决方案都没有解决内存泄漏问题。

感谢。

0 个答案:

没有答案