Python tkinter,matplotlib:内存使用

Python tkinter,matplotlib:内存使用,python,python-2.7,memory,matplotlib,tkinter,Python,Python 2.7,Memory,Matplotlib,Tkinter,我有一个简单的程序,可以使用tkinter创建GUI。GUI包含一个按钮,每次按下该按钮时都会创建一个新的tkinterToplevel窗口。每个顶级窗口都包含一个从自定义图形类创建的matplotlib绘图 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure from Tkinter import * class MainGUI(Tk):

我有一个简单的程序,可以使用
tkinter
创建GUI。GUI包含一个按钮,每次按下该按钮时都会创建一个新的tkinter
Toplevel
窗口。每个顶级窗口都包含一个从自定义
图形
类创建的matplotlib绘图

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from Tkinter import *

class MainGUI(Tk):
    def __init__(self):
        Tk.__init__(self)
        Button(self, text="new_child", command=self.new_child).pack()
        self.mainloop()

    def new_child(self):
        self.tl = TL()

class TL(Toplevel):
    def __init__(self, **kw):
        Toplevel.__init__(self, **kw)
        self.data = "00000000000"*10000000  # just some data to analyze memory allocation 
        self._figure = MyFigure(self.data)
        self._canvas = FigureCanvasTkAgg(self._figure, master=self)
        self._canvas.get_tk_widget().grid(row=0, column=0, sticky="NSWE")

class MyFigure(Figure):
    def __init__(self, data):
        super(MyFigure, self).__init__()
        self._data = data

if __name__ == '__main__':
    MainGUI()
程序按预期工作,唯一的问题是关闭窗口不会释放任何内存

当从顶层窗口中删除
时,已用内存被正确释放,因此我假设
导致内存泄漏

我了解到引用计数不适用于使用matplotlibs pyplot接口创建的
对象,但这不适用于我的示例。(详情请参阅)

我不明白这里发生了什么,所以任何帮助都将不胜感激

提前谢谢

编辑
我忘了提到,我已经尝试使用
gc.collect()
手动调用垃圾收集器,但是没有用

关闭顶级窗口后,尝试调用
gc.collect()

def new_child(self):
    tl = TL()
    self.wait_window(tl)   # Wait for tl to be closed before continuing execution
    del tl
    gc.collect()

关闭顶级窗口后,尝试调用
gc.collect()

def new_child(self):
    tl = TL()
    self.wait_window(tl)   # Wait for tl to be closed before continuing execution
    del tl
    gc.collect()

谢谢你提出这个问题,谢谢你的回答,这对我帮助很大。我发现自己在一个稍微复杂一些的GUI中也遇到了类似的情况。尽管应用了这里给出的解决方案,我还是遇到了内存泄漏。似乎向Tkinter变量(例如IntVar、DoubleVar等)添加跟踪会阻止顶级窗口被正确破坏,并导致泄漏在销毁时手动删除跟踪修复了此问题。让我举一个代码泄漏的例子,以及我找到的修复方法。我希望它能帮助别人

初步: 首先,使用Josselin给出的
new_child
的更正版本:

def new_child(self):
    tl = TL()
    self.wait_window(tl)   # Wait for tl to be closed before continuing execution
    del tl
    gc.collect()
然后,出现内存泄漏的代码(由跟踪引起):

最后,修复程序(在销毁时手动删除跟踪):


谢谢你提出这个问题,谢谢你的回答,这对我帮助很大。我发现自己在一个稍微复杂一些的GUI中也遇到了类似的情况。尽管应用了这里给出的解决方案,我还是遇到了内存泄漏。似乎向Tkinter变量(例如IntVar、DoubleVar等)添加跟踪会阻止顶级窗口被正确破坏,并导致泄漏在销毁时手动删除跟踪修复了此问题。让我举一个代码泄漏的例子,以及我找到的修复方法。我希望它能帮助别人

初步: 首先,使用Josselin给出的
new_child
的更正版本:

def new_child(self):
    tl = TL()
    self.wait_window(tl)   # Wait for tl to be closed before continuing execution
    del tl
    gc.collect()
然后,出现内存泄漏的代码(由跟踪引起):

最后,修复程序(在销毁时手动删除跟踪):


你怎么做你的测试?假设对象不再使用,我希望垃圾收集器最终会清理内存。我已经尝试手动调用gc,但没有帮助。测试非常简单。打开/关闭子窗口,您将看到程序使用的内存随着每个创建的子窗口的增加而增加。您是否可以在销毁窗口之前覆盖
TL
类的
destroy
方法以删除图形?您如何进行测试?假设对象不再使用,我希望垃圾收集器最终会清理内存。我已经尝试手动调用gc,但没有帮助。测试非常简单。打开/关闭子窗口,您将看到程序使用的内存随着每个创建的子窗口的增加而增加。您是否可以在销毁窗口之前覆盖
TL
类的
destroy
方法以删除图形?