2014-12-20 23 views
1

我一直在使用Tkinter在Python中进行一个非常简单的游戏,只是为了查看我是否可以。有一个包含所有游戏对象的List,并且List循环的主循环的每个记号都被循环,List中的每个对象都将自己绘制到窗口中。从内存中清除没有引用的Python对象

每当用户触发一个激光器,一个新的激光对象被动态地添加到列表中,而不将其分配给一个变量。在简单的形式,它是这样的:

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

当激光绘制它本身测试其位置在窗口中,当它达到一定点时,它从列表中移除,不再绘制。它没有其他参考,但似乎无论如何都留在记忆中。

虽然发射激光,并因此创建多个激光的对象,程序的内存使用情况不断地增高。作为测试,我这样做直到内存使用量达到10MB,然后我让程序在那里坐了一个小时,看看是否有没有引用的激光对象会被垃圾收集,并且程序的内存使用率将会消失退缩,但它从来没有。它保持在10 MB。

在这种情况下,有没有别的东西,我需要做的就是将垃圾回收的激光适当的对象,使他们不会继续占用内存和程序内存总使用量可以保持稳定?

+0

我的tkinter知识有点生疏,但我认为我们需要看到创建激光对象的代码。 –

+0

尝试调用'gc.collect()',然后检查'gc.garbage'的内容。这可能是因为LaserObject正在创建一个内部对象,由于某种原因它不能被释放。如果在垃圾列表中有LaserObject,那么你是定义一个'__del__'方法还是继承一个具有一个类的类? – Dunes

+0

我不认为即使当对象被删除并且未使用的对象被垃圾收集时,Python解释器也不会将内存返回给操作系统。这意味着进程的内存占用将永远不会变小。 – martineau

回答

0

原来,这个问题曾与没有从内存中删除一个标签做。

最初每个有LaserObject在它内部标签的激光图像绘制到。后来我切换到直接在画布上绘制图像,但Label对象保留在LaserObject内部,没有正确删除。

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

对于这种情况最好的解决办法是允许标签留在LaserObject,但添加代码,当LaserObject从项目列表中删除销毁标签。就像这样:

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

这告诉Tk的清理该标签对象的所有内部的代码,它使内存使用稳定。

相关问题