Matplotlib错误导致内存泄漏,我该如何释放这些内存?

15

我正在运行一个包括matplotlib的django应用程序,并允许用户指定图形的轴。这可能会导致'Overflow Error: Agg complexity exceeded'

当发生这种情况时,最多会占用100MB的RAM。通常情况下,我使用fig.gcf()plot.close()gc.collect()来释放内存,但是与错误相关联的内存似乎并不与绘图对象相关。

有人知道如何释放该内存吗?

谢谢。

以下是一些代码,它给出了Agg Complexity Error。

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np      
import gc

a = np.arange(1000000)
b = np.random.randn(1000000)

fig = plt.figure(num=1, dpi=100, facecolor='w', edgecolor='w')
fig.set_size_inches(10,7)
ax = fig.add_subplot(111)
ax.plot(a, b)

fig.savefig('yourdesktop/random.png')   # code gives me an error here

fig.clf()    # normally I use these lines to release the memory
plt.close()
del a, b
gc.collect()
2个回答

20

当使用for循环保存多个绘图时,此解决方案可解决“MemoryError: In RendererAgg: Out of memory”错误。 - richinex

15

我假设您至少可以运行一次您发布的代码。问题只会在多次运行发布的代码后才会显现出来。如果是这样,以下方法可以避免问题,但实际上并不确定问题的根源所在。也许这是一个不好的解决方案,但在紧急情况下它有效:只需使用multiprocessing在单独的进程中运行占用内存的代码。您无需担心fig.clf()plt.close()del a,bgc.collect()。所有内存都将在进程结束时释放。

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np      

import multiprocessing as mp

def worker():
    N=1000000
    a = np.arange(N)
    b = np.random.randn(N)

    fig = plt.figure(num=1, dpi=100, facecolor='w', edgecolor='w')
    fig.set_size_inches(10,7)
    ax = fig.add_subplot(111)
    ax.plot(a, b)

    fig.savefig('/tmp/random.png')   # code gives me an error here

if __name__=='__main__':
    proc=mp.Process(target=worker)
    proc.daemon=True
    proc.start()
    proc.join()

你也不必使用proc.join()join会阻塞主进程直到worker完成。如果省略join,则主进程仅继续进行,而worker进程在后台工作。


我发布的代码第一次运行失败了。它是为了重新创建用户在高采样率数据上在y轴上缩放过多的特殊情况。如果绘图看起来像一片蓝色的洗涤剂而没有显示任何白色背景,那么代码就会失败。然而,你的解决方案似乎是更好的内存管理方式。我是一个新手,我不完全理解if __name__ == '__main__':块中发生了什么。我将尝试将其添加到我的代码中。你能指向一个解释正在发生什么的资源吗?或者你能提供一个快速的解释。谢谢。 - sequoia
@sequoia:在这种情况下,也许您需要限制用户,以便用户在任何情况下都不能请求绘制1e6个点。if __name__...块除非您在Windows上,否则不是必需的。我很乐意尝试解答您有关特定问题的任何问题,但我认为在这种情况下,一切都比我可以在此处更好地解释了。 - unutbu
谢谢,这是一个有用的链接。我将使用您的实现,并采纳您的建议来限制用户请求的范围。 - sequoia
哇!我简直不敢相信这个解决方法是如此巧妙地为我解决了一个类似的问题。 当然,它并不是解决根本问题的方法。但在紧急情况下,这是一个很好的技巧。 - Eric McLachlan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接