【问题标题】:xPython savefig memory leak unresolved with formerly proposed solutions以前提出的解决方案无法解决 xPython savefig 内存泄漏
【发布时间】:2013-11-18 22:04:34
【问题描述】:

编辑:已解决

但我不确定如何...我尽可能多地转移到 pylab 而不是 pyplot,实现了 [here][1] 描述的多处理方法,那时它工作正常。然后为了查明问题,我逐步反转了我的代码。但即使没有多重处理,即使使用 pyplot 等,它也能继续工作。只有当我现在取消 fig.clf() 时它才不起作用,这似乎是大多数人所经历的,但最初并不是我的问题。好吧,也许是这样,也许 clf() 语句不在正确的位置或其他地方。谢谢!

编辑:问题仍未解决

这非常令人惊讶。我现在将我的 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)

我一步一步、一行一行地做所有事情,当点击外部函数中的 savefig() 函数时,RAM 肯定会上升。增加了大约 500MB。然后当回到主脚本时,该内存不会被释放。 外部功能不应该清除所有内容吗?我错过了一些东西......

原帖:

我正在使用 python EDP 7.3-2(32 位)(python 2.7.3)。

我有一个程序可以进行一些计算,然后将一些结果映射出来并使用 matplotlib 保存图像。

这是一个相当大的数据量,如果我尝试映射和保存太多图像,我会达到内存限制。我不应该这样做,因为我重复使用相同的数字,并且不创建新变量。我为此苦苦挣扎了一段时间,尝试了所有图形清除/删除等解决方案,更改了 matplotlib 使用的后端,但什么也没做,每次代码命中 savefig 函数时,它都会增加大量内存并且不会占用稍后关闭。

我远不是内存方面的专家(或者是 python),但这是我使用模块 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

但内存仍在不断增长,很快我就达到了内存限制。

非常感谢!

【问题讨论】:

  • 如果你在 savefigs 之间使用 'gc.collect()' 会发生什么?
  • 谢谢!我实际上在无花果之间做 gc.collect。
  • 保存的代码路径取决于你图中的艺术家。请提供完整(但最少)的代码来演示问题。
  • 我不太明白“艺术家”是什么意思,但我在路径、人物构造等方面添加了更多细节。谢谢!
  • 您是否尝试过here找到的解决方案?

标签: python memory-leaks matplotlib


【解决方案1】:

谷歌搜索的轶事证据似乎表明,在 savefig 之后执行“matplotlib.pyplot.close”将回收/释放与该图相关的内存。有关所有调用选项,请参阅 pyplot 文档。

【讨论】:

    【解决方案2】:

    我忘记了在哪个堆栈溢出线程/网站上找到了这个解决方案,但是直接使用这个图(而不是接触 pyplot 状态机)通常可以解决问题。所以:

    fig = figure.Figure()
    canvas = FigureCanvas(fig)
    ...
    canvas.print_figure(outpath+pftspatialnames[i]+'testredtarget.png', dpi=500)
    

    【讨论】:

    • 谢谢,我试过了,发现它对于一些内存问题是成功的。就我而言,它没有帮助。终于找到了解决办法,贴在原帖里。
    【解决方案3】:

    编辑:已解决

    但我不确定如何...我尽可能多地转移到 pylab 而不是 pyplot,实现了 [here][1] 描述的多处理方法,那时它工作正常。然后为了查明问题,我逐步反转了我的代码。但即使没有多处理,即使使用 pyplot 等,它也能继续工作。只有当我现在取消 fig.clf() 时它才不起作用,这似乎是大多数人所经历的,但最初并不是我的问题。好吧,也许是,也许 clf() 语句不在正确的位置或其他地方。谢谢

    【讨论】:

      猜你喜欢
      • 2011-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 2010-10-25
      • 2013-09-02
      • 2012-04-05
      相关资源
      最近更新 更多