我一直在使用Tkinter开发一个非常简单的Python游戏,只是为了看看我是否可以。有一个List,它包含所有的游戏对象,并且List循环遍历主循环的每个tick,并且List中的每个对象都将自己绘制到窗口。
每当用户触发激光时,会将新的激光对象动态添加到List中,而不会将其分配给变量。简化形式,就像这样:
if buttonIsPressed:
game.itemlist.append(LaserObject())
当激光自己绘制时,它会测试它在窗口中的位置,当它到达某个点时,它会从列表中移除它,并且不再被绘制。它没有其他参考,但无论如何它似乎都留在了记忆中。
在激发激光并因此产生更多激光对象时,程序的内存使用率会上升。作为一个测试,我做到了这一点,直到内存使用量达到10MB,然后我让程序只是坐在那里一个小时,看看是否有任何没有引用的激光对象会被垃圾收集,程序的内存使用量将会增加退缩,但它从来没有。它保持在10 MB。
在这种情况下,我还需要做些什么来让这些激光对象正确地进行垃圾收集,这样他们就不会继续占用内存,程序的整体内存使用率会保持稳定吗?
答案 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对象的所有内部代码,并保持内存使用稳定。