gpt4 book ai didi

python - wxpython 应用程序中严重的内存泄漏

转载 作者:行者123 更新时间:2023-11-30 23:43:43 24 4
gpt4 key购买 nike

我正在以某种方式构建一个相当复杂的 wxPython 应用程序,使用 ode 进行物理建模,使用 openGL 进行渲染,使用 wx 进行 UI。一切都进展顺利,直到应用程序开始崩溃。经过几天毫无进展后,我终于注意到我的应用程序正在泄漏内存。我能够将一些以相当惊人的速度泄漏的东西提炼成一个很小的示例脚本:

#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------

import wx
import wx.propgrid as wxpg
import random

class CoordProperty(wxpg.PyProperty):
def __init__(self, label, name, value=(0,0,0)):
wxpg.PyProperty.__init__(self, label, name)
self.SetValue(value)

def GetClassName(self):
return "CoordProperty"

def GetEditor(self):
return "TextCtrl"

def ValueToString(self, value, flags):
x,y,z = value
return "%f,%f,%f"%(x,y,z)


app = wx.App(False)
frame = wx.Frame(None, -1, "Test")
pg = wxpg.PropertyGridManager(frame)
props = {}

for i in range(1000):
prop_name = "prop_%d"%i
prop = CoordProperty("Coord", prop_name)
pg.Append(prop)
props[prop_name] = prop

def OnTimer(event):
global props
for key in props:
props[key].SetValue((random.random(), random.random(), random.random()))

timer = wx.Timer(frame, 1)
frame.Bind(wx.EVT_TIMER, OnTimer)
timer.Start(10) # 100Hz

frame.Show()

app.MainLoop()
timer.Stop()

该示例创建一个框架,并将 wxPropertyGrid 放入其中。它派生出一个显示 3D 坐标值的属性,创建一千个坐标值,然后通过以 100Hz 运行的计时器将每个坐标值更新为随机值。其泄漏速度接近 10Mb/秒,并最终崩溃。它通常也会在关闭时崩溃。

我在 Windows 7 上使用 python 2.7 和 wx 2.9.3.1 msw(经典)。

如果我用内置属性(例如 wxpg.FloatProperty)替换派生的 CoordProperty,并相应地修改代码,泄漏就会消失。

有什么想法吗?或者我应该提交一个wx bug?我什至可以删除派生属性类中函数 ValueToString 的定义,但应用程序仍然会泄漏。

最佳答案

我使用以下代码来计算对象:

def output_memory():
d = defaultdict(int)
for o in gc.get_objects():
name = type(o).__name__
d[name] += 1

items = d.items()
items.sort(key=lambda x:x[1])
for key, value in items:
print key, value

发现你的程序每次事件都会增加1000个元组。因此,当您调用 props[key].SetValue() 时,gc 尚未收集上一个值。这可能是wxpg的一个bug,我们可以通过使用([x],[y],[z])来保存值来解决这个bug,这样你就可以更新值而无需调用设置值():

for name, prop in props.iteritems():
value = prop.GetValue()
value[0][0] = random()
value[1][0] = random()
value[2][0] = random()
pg.Refresh()

完整代码如下:

import wx
import wx.propgrid as wxpg
from random import random
import gc

from collections import defaultdict

def output_memory():
d = defaultdict(int)
for o in gc.get_objects():
name = type(o).__name__
d[name] += 1

items = d.items()
items.sort(key=lambda x:x[1])
for key, value in items:
print key, value

class CoordProperty(wxpg.PyProperty):
def __init__(self, label, name):
wxpg.PyProperty.__init__(self, label, name)
self.SetValue(([0],[0],[0]))

def GetClassName(self):
return "CoordProperty"

def GetEditor(self):
return "TextCtrl"

def GetValueAsString(self, flags):
x,y,z = self.GetValue()
return "%f,%f,%f"%(x[0],y[0],z[0])

app = wx.App(False)
frame = wx.Frame(None, -1, "Test")
pg = wxpg.PropertyGridManager(frame)
props = {}

for i in range(1000):
prop_name = "prop_%d"%i
prop = CoordProperty("Coord", prop_name)
pg.Append(prop)
props[prop_name] = prop

def OnTimer(event):
for name, prop in props.iteritems():
value = prop.GetValue()
value[0][0] = random()
value[1][0] = random()
value[2][0] = random()
pg.Refresh()
#output_memory()

timer = wx.Timer(frame, 1)
frame.Bind(wx.EVT_TIMER, OnTimer)
timer.Start(10)

frame.Show()

app.MainLoop()
timer.Stop()

关于python - wxpython 应用程序中严重的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10610570/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com