Matplotlib imshow中的内存泄漏问题

4
我在matplotlib.imshow中发现了内存泄漏问题。我了解类似的问题(例如Matplotlib imshow中过多的内存使用),并且我已经阅读了相关的ironpython主题 (https://github.com/ipython/ipython/issues/1623/)。
我认为以下代码应该在运行时(如果没有内存泄漏)消耗恒定的内存量。然而,实际上它每次迭代都会增加。
我正在运行我能找到的最新版本(matplotlib-1.2.0rc3.win32-py2.7和numpy-1.7.0.win32-py2.7),但问题仍然存在。我没有保留imshow的返回值,并且事实上我明确地删除了它,因此我认为IronPython讨论中的注意事项不适用。行为在循环内部有或没有明确分配和删除是相同的。
我在matplotlib-1.2.0.win32-py2.7中看到的行为是相同的。
每个迭代似乎都会保留生成图像所需的任何内存。我选择了一个大型(1024x1024)随机矩阵来使每个图像的大小变得有趣。
我正在运行带有2G物理内存的Win7 pro,32位python2.7.3(因此是内存错误),以及上述numpy和matplotlib软件包。当我运行440次左右时,下面的代码会出现内存错误。Windows任务管理器在失败时报告了1860232K的内存使用。
以下是演示泄漏的代码:
IMAGE_SIZE = 1024
import random
RANDOM_MATRIX = []
for i in range(IMAGE_SIZE):
    RANDOM_MATRIX.append([random.randint(0, 100) for each in range(IMAGE_SIZE)])

def exercise(aMatrix, aCount):
    for i in range(aCount):
        anImage = imshow(aMatrix, origin='lower left', vmin=0, vmax=100)
        del(anImage)

if __name__=='__main__':
    from pylab import *
    exercise(RANDOM_MATRIX, 4096)

我可以使用PIL而不是matplotlib来渲染图像。如果没有解决方法,我认为这对于matplotlib来说是一个致命问题。


2
确认一下,这不是内存泄漏(或者说不会阻止程序运行)。当你调用imshow时,每次都会向Axes实例中添加一个新的图像。删除“anImage”引用并不会从Axes中删除该图像。如你所提出的解决方案,你可以在Image实例上使用“set_data”,或者调用“anImage.remove()”来从Axes中删除该图像。希望对你有所帮助。 - pelson
2个回答

1

我想我找到了一个解决方法,我没有完全意识到imshow有多么沉重。

答案是只调用一次imshow,然后对于每个随后的图像,使用RANDOM_MATRIX调用set_data。

问题解决了!


1
作为一个提示,图中有很多关于“anImage”的引用,因此删除本地引用并没有任何作用。如果您添加“anImage.remove()”,可能会更好。我不会说这是一个解决方法,因为这不是一个错误。它的行为是正确的,而且正好做了你告诉它要做的事情(即使那不是你的本意)。 - tacaswell

1

我曾经苦苦钻研这个问题,因为很多帖子都讨论了这个问题,但似乎没有人提供一个可行的例子。

首先,当使用自己没有制作的库时,永远不应该使用 from ... import * 语法——因为你永远无法确定它是否声明了与你冲突的符号。

然后,仅仅调用 set_data 是不足以解决这个问题的,原因有三:

  1. 你没有提到这个 set_data 是从哪里调用的。它不是一个普通的函数,而是一个对象的方法......哪个对象?
  2. 仅仅使用 set_data 是不够的,如果你没有其他东西来“激活”这些变化的话。有时会在另一个图中透明地发生,因为它需要激活,但如果没有,你就需要自己调用 flush_events()
  3. 如果你没有用可以用于设置它的颜色映射的值调用 imshow(),那么设置数据将不起作用。

这里有一个可行的解决方案(link):


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