Memory leaks matplotlib imshow中的内存泄漏

Memory leaks matplotlib imshow中的内存泄漏,memory-leaks,matplotlib,Memory Leaks,Matplotlib,我在matplotlib.imshow中发现了内存泄漏。我知道类似的问题(如),并且我已经阅读了相关的ironpython线程() 我相信下面的代码应该(在没有内存泄漏的情况下)在运行时消耗恒定的内存量。相反,它会随着每次迭代而增长 我正在运行我能找到的最新版本(matplotlib-1.2.0rc3.win32-py2.7和numpy-1.7.0.win32-py2.7),问题仍然存在。我没有保留imshow的返回值,事实上我显式地删除了它,因此我认为IronPython讨论中的注释不适用。在

我在matplotlib.imshow中发现了内存泄漏。我知道类似的问题(如),并且我已经阅读了相关的ironpython线程()

我相信下面的代码应该(在没有内存泄漏的情况下)在运行时消耗恒定的内存量。相反,它会随着每次迭代而增长

我正在运行我能找到的最新版本(matplotlib-1.2.0rc3.win32-py2.7和numpy-1.7.0.win32-py2.7),问题仍然存在。我没有保留imshow的返回值,事实上我显式地删除了它,因此我认为IronPython讨论中的注释不适用。在循环中,无论是否使用显式赋值和del,行为都是相同的

我在matplotlib-1.2.0.win32-py2.7中看到了相同的行为

每次迭代似乎都会保留图像所需的任何内存。我已经 选择一个大的(1024x1024)随机矩阵,使每个图像的大小都非常大

我使用2G物理RAM、32位Python 2.7.3(因此出现内存错误)以及上述numpy和matplotlib包运行Win7 pro。下面的代码在迭代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的一个表演障碍。

我认为我找到了一个变通方法,我没有完全意识到imshow的重量级

答案是只调用一次imshow,然后使用随机矩阵为每个后续图像调用set_数据


问题解决了

我努力让它发挥作用,因为很多帖子都在谈论这个问题,但似乎没有人关心提供一个有效的例子

首先,你不应该使用来自。。。import*语法,当使用一个您自己没有创建的库时-因为,您永远无法确定它没有声明一个与您的符号冲突的符号

然后,调用
set_data
不足以解决此问题-原因有三:

  • 您没有提到从何处调用此set_数据。这不是一个问题 正常函数,但对象的方法。。。哪个物体
  • 如果您没有需要的内容,仅设置_数据是不够的 “激活”更改。有时它会透明地发生 因为另一个绘图会激活它,但如果它不激活,则需要 自己调用
    flush\u events()
  • 如果未使用设置数据的值调用
    imshow()
    ,则设置数据将不起作用 可用于设置其颜色贴图
  • 这里有一个可行的解决方案

    IMAGE_SIZE = 500
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    plt.ion()
    
    fig1, ax1 = plt.subplots()
    fig2, ax2 = plt.subplots()
    
    # this example doesn't work because array only contains zeroes
    array = np.zeros(shape=(IMAGE_SIZE, IMAGE_SIZE), dtype=np.uint8)
    axim1 = ax1.imshow(array)
    
    array[0, 0] = 99 # this value allow imshow to initialise it's color scale
    axim2 = ax2.imshow(array)
    
    del array
    
    for _ in range(50):
        print(".", end="")
        matrix = np.random.randint(0, 100, size=(IMAGE_SIZE, IMAGE_SIZE), dtype=np.uint8)
        
        axim1.set_data(matrix)
        fig1.canvas.flush_events()
        
        axim2.set_data(matrix)
        fig1.canvas.flush_events()
    print()
    

    需要注意的是,图中有大量对
    anImage
    的引用,因此删除本地引用没有任何作用。如果您添加
    anImage.remove()
    ,您的运气可能会更好。我不会说这是一个解决办法,因为这不是一个bug。它的行为是正确的,并且完全按照你告诉它的去做(即使这不是你的意思)。这不是内存泄漏(或者确实是显示停止)。调用imshow时,每次都将向Axis实例添加一个新图像。删除“anImage”参考不会从轴上删除图像。正如您的解决方案所建议的,您可以在图像实例上设置数据,或者调用
    anImage.remove()
    从轴上删除图像。嗯