【问题标题】:How to prevent memory leakage in wxPython subclass?如何防止 wxPython 子类中的内存泄漏?
【发布时间】:2013-04-29 23:09:36
【问题描述】:

我正在运行 Python 2.7、wxPython 2.8.12.1 和 Windows 7。

我正在开发一个将大数据对象传递给 wx.Frame 并创建交互式绘图的程序。目标是遍历许多数据对象,为每个数据对象创建新窗口和绘图。

我遇到的问题是,对于我的 wx.Frame 子类的每个新实例,内存使用量都会急剧增加。

下面的代码重现了我的问题。

第一个循环创建 10 个对象,每个对象包含一个大小递减的数组。在此循环运行时,内存使用量(根据 Windows 任务管理器)随着每次迭代而下降。

第二个循环创建了 10 个保存相同数组的 wx.Frame 对象。但是,现在内存使用量稳步增加到 1 GB。

import numpy as np
import time
import wx


class MyClass():

    def __init__(self, i):
        self.x = np.arange(0, i*5000000)


#While this loop runs, memory usage decreases
for i in [10,9,8,7,6,5,4,3,2,1]:
    print(i)
    m = MyClass(i)
    time.sleep(2)


class wxWindow(wx.Frame):

    def __init__(self,i = None):
        super(wxWindow,self).__init__(None)
        self.x = np.arange(0, i*5000000)


#While this loop runs, memory usage increases
#until the program crashes.
for i in [10,9,8,7,6,5,4,3,2,1]:
    print(i)
    app = wx.App()
    app.frame = wxWindow(i)
    app.frame.Show(True)
    app.MainLoop()
    app.Destroy()

我可以通过两种方法阻止内存泄漏:

1) 通过将变量“x”设为局部变量(即删除“self.”):

x = np.arange(0, i*5000000)

2) 使用弱引用:

self.x = weakref.ref(np.arange(0, i*5000000))

我不能使用方法#1,因为我需要整个班级都可以使用大型数据对象。我对weakref 对象一无所知,但到目前为止,我还没有运气好使用对我的数据对象的弱引用(总是得到“weakref 对象没有属性”错误)。

【问题讨论】:

    标签: python memory-leaks wxpython weak-references


    【解决方案1】:

    将代码的最后一部分更改为:

    app = wx.App()
    for i in [10,9,8,7,6,5,4,3,2,1]:
        print(i)
        frame = wxWindow(i)
        frame.Show(True)
        app.MainLoop()
    

    wx.App 作为单例运行(阅读this thread),因此每个进程只需要 1 个 wx.App 实例。你做了10个。无论如何,这会治愈你的记忆问题。

    【讨论】:

    • 完美!几个星期以来,我一直在努力解决这个问题。谢谢。
    • 让我补充您提出问题的方式。包含实际运行以解释问题的代码可以更容易理解并提出解决方案。
    【解决方案2】:

    似乎您可以将x 设为类属性

    class wxWindow(wx.Frame):
        x = np.arange(0, i*5000000)
        def __init__(self, i=None):
            super(wxWindow, self).__init__(None)
    

    另一种方法是明确地delx

    del app.frame.x
    

    终于到了;可能是 wxWindow 的一种方法可以处理清理工作。例如

    class wxWindow(wx.Frame):
    
        def __init__(self,i=None):
            super(wxWindow, self).__init__(None)
            self.x = np.arange(0, i*5000000)
    
        def close(self):  # you'll have to find the correct name in the docs
            del self.x
            super(wxWindow, self).close()
    

    【讨论】:

      猜你喜欢
      • 2010-12-20
      • 1970-01-01
      • 2011-08-09
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 2016-07-10
      相关资源
      最近更新 更多