2009-06-23 171 views
31

我已經創建了一些python代碼,它在循環中創建一個對象,並在每次迭代中用相同類型的新代碼覆蓋此對象。這是10.000次,Python每秒鐘佔用7MB的內存,直到使用我的3GB RAM。有誰知道從內存中刪除對象的方法嗎?Python垃圾回收

+0

相關:http://stackoverflow.com/questions/759906/sys-getrefcount-continuation/759970#759970 – codeape 2009-06-23 22:32:07

回答

16

你還沒有提供足夠的信息 - 這取決於你正在創建的對象的具體細節,以及你在循環中做了什麼。如果該對象不創建循環引用,則應在下一次迭代中解除分配。例如,代碼

for x in range(100000): 
    obj = " " * 10000000 

不會導致不斷增加的內存分配。

+0

我在我的對象中創建循環引用。不能手動刪除它嗎? – utdiscant 2009-06-23 22:14:38

+8

Python將自動收集帶有循環引用的對象*,除非*引用循環中的任何對象都有__del__方法。如果是這樣的話,垃圾對象將被移動到gc.garbage列表中,並且您將不得不手動中斷參考週期。儘量避免同時使用__del__方法和參考週期。 – Miles 2009-06-23 22:21:28

+5

避免引用循環的一個解決方案是使用weakrefs:http://docs.python.org/library/weakref.html – Miles 2009-06-23 22:27:16

12

這是一箇舊的錯誤,已經在python 2.5中修正了一些類型。發生了什麼事情是,python並不擅長收集空列表/字典/ tupes /浮動/整數等內容。在Python 2.5中,這是固定的......主要是。然而,浮點數和整數是用於比較的單例,因此一旦創建了其中一個,只要解釋程序還活着,它就會一直保留。在處理大量漂浮物時,我被這種最糟糕的東西咬了,因爲他們有一種獨特的惡習。這是特點for python 2.4和更新關於它被摺疊成python 2.5

我發現它周圍的最佳方式是升級到python 2.5或更新,以照顧列表/字典/元組問題。對於數字來說唯一的解決方案是不要讓大量的數字進入Python。我已經用我自己的包裝器完成了一個C++對象,但我有一個印象numpy.array會給出類似的結果。

作爲後腳本,我不知道發生了什麼事這在Python 3,但我懷疑數字仍然是一個單獨的部分。所以內存泄漏實際上是該語言的一個特徵。

+1

儘管如此,這應該不完全是造成問題的原因;即使Python 2.4應該重用釋放的內存(它只是沒有返回到操作系統)。 – Miles 2009-06-23 22:19:06

1

這裏有一兩件事你可以在REPL做強制變量的解引用:

>>> x = 5 
>>> x 
5 
>>> del x 
>>> x 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'x' is not defined 
5

如果要創建循環引用,你的對象不會立即釋放,但要等待一個GC循環運行。

您可以使用weakref模塊來解決這個問題,或者在使用後明確地刪除對象。

3

我發現,在我的情況(與Python 2.5.1),與包括有__del__()方法,不僅是垃圾收集不及時發生類循環引用,從來沒有得到所謂的我的對象的__del__()方法,即使劇本退出了。所以我用weakref來打破循環引用,一切都很好。

榮譽萬里誰在他的評論所提供的所有信息,我把這個在一起。

19

我認爲這是循環引用(雖然這個問題不明確這方面的信息。)來解決這個問題

一種方法是手動調用垃圾收集。當您手動運行垃圾收集器時,它也會掃描循環引用的對象。

import gc 

for i in xrange(10000): 
    j = myObj() 
    processObj(j) 
    #assuming count reference is not zero but still 
    #object won't remain usable after the iteration 

    if !(i%100): 
     gc.collect() 

這裏不經常運行垃圾回收器,因爲它有自己的開銷,例如,如果你在每個循環中運行垃圾收集器,解釋將變得非常緩慢。