清除Python对象而没有内存引用

时间:2014-12-20 09:31:45

标签: python memory tkinter

我一直在使用Tkinter开发一个非常简单的Python游戏,只是为了看看我是否可以。有一个List,它包含所有的游戏对象,并且List循环遍历主循环的每个tick,并且List中的每个对象都将自己绘制到窗口。

每当用户触发激光时,会将新的激光对象动态添加到List中,而不会将其分配给变量。简化形式,就像这样:

if buttonIsPressed:
    game.itemlist.append(LaserObject())

当激光自己绘制时,它会测试它在窗口中的位置,当它到达某个点时,它会从列表中移除它,并且不再被绘制。它没有其他参考,但无论如何它似乎都留在了记忆中。

在激发激光并因此产生更多激光对象时,程序的内存使用率会上升。作为一个测试,我做到了这一点,直到内存使用量达到10MB,然后我让程序只是坐在那里一个小时,看看是否有任何没有引用的激光对象会被垃圾收集,程序的内存使用量将会增加退缩,但它从来没有。它保持在10 MB。

在这种情况下,我还需要做些什么来让这些激光对象正确地进行垃圾收集,这样他们就不会继续占用内存,程序的整体内存使用率会保持稳定吗?

1 个答案:

答案 0 :(得分:0)

事实证明,问题与标签没有从内存中删除有关。

最初每个LaserObject都有一个标签,里面有激光图像。后来我切换到直接在画布上绘制图像,但Label对象仍然在LaserObject中,并且没有被正确删除。

当我完全从LaserObject中删除Label时,图像开始在画布上疯狂地闪烁,可能与标签保留对图像的引用有关,因此有助于它不会过早收集垃圾或类似的东西。

这种情况的最佳解决方案是允许Label保留在LaserObject中,但添加代码以在从项目列表中删除LaserObject时销毁Label。像这样:

if laser.y == past_edge_of_window:
    self.game.itemlist.remove(laser)
    self.label.destroy()

这告诉Tk清理该Label对象的所有内部代码,并保持内存使用稳定。