2014-12-20 51 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的清理該標籤對象的所有內部的代碼,它使內存使用穩定。

相關問題