回答
Python的標準引用計數機制不能釋放週期,所以你的例子中的結構會泄漏。
的supplemental garbage collection facility,但是,在默認情況下啓用,並且應該能夠釋放該結構,如果沒有它的組件可達從外面再和他們沒有__del__()
方法。
如果他們這樣做,垃圾收集器will not free them,因爲它不能確定一個安全的命令來運行這些__del__()
方法。
應該明確聲明,您稱爲「補充」的GC在默認情況下在Python –
@Eli中啓用,您是對的,因此回答相應更新。 –
萬歲!至少,對GC和ref counter以及不使用「垃圾回收器」作爲「引用計數機制」的同義詞的人們(你和Raymond Hettinger)不要混淆!很久以來,我一直對這樣的事實感到困惑,但我一直在閱讀文本,人們在這些文本中表達了他們的想法,好像GC是殺死沒有被引用的對象的責任。在你的回答中,差異是完美表達和清晰的。謝謝。因此,+1 – eyquem
Python的GC被設計成遍歷所有活對象沒有外部引用來定位並消除參考週期。
您可以通過運行gc.collect()
然後打印gc.garbage
和gc.get_objects來驗證發生了什麼。
如果你使用weakrefs作爲父指針,那麼GC將正常發生。
爲了擴展Frédéric的答案,文檔的the "reference counts" section很好地解釋了補充週期檢測。
因爲我發現講解的東西的好方法,以確認我的理解,這裏有一些例子......有了這兩個類:
class WithDel(object):
def __del__(self):
print "deleting %s object at %s" % (self.__class__.__name__, id(self))
class NoDel(object):
pass
創建一個對象,並從a
失去了參考觸發__del__
方法,由於裁判計數:
>>> a = WithDel()
>>> a = None # leaving the WithDel object with no references
deleting WithDel object at 4299615184
如果我們兩個對象沒有__del__
方法之間的參考迴路,一切還是無泄漏,T他的時間感謝週期檢測。首先,使垃圾收集調試輸出:
>>> import gc
>>> gc.set_debug(gc.DEBUG_COLLECTABLE | gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS)
然後使兩個對象之間的參考循環:
>>> a = NoDel(); b = NoDel()
>>> a.other = b; b.other = a # cyclical reference
>>> a = None; b = None # Leave only the reference-cycle
>>> gc.collect()
gc: collectable <NoDel 0x10046ed50>
gc: collectable <NoDel 0x10046ed90>
gc: collectable <dict 0x100376c20>
gc: collectable <dict 0x100376b00>
4
>>> gc.garbage
[]
(該dict
是從物體內部__dict__
屬性)
所有很好,直到即使其中一個對象在循環中也包含一個__del__
方法:
>>> a = NoDel(); b = WithDel()
>>> a.other = b; b.other = a
>>> a = None; b = None
>>> gc.collect()
gc: uncollectable <WithDel 0x10046edd0>
gc: uncollectable <dict 0x100376b00>
gc: uncollectable <NoDel 0x10046ed90>
gc: uncollectable <dict 0x100376c20>
4
>>> gc.garbage
[<__main__.WithDel object at 0x10046edd0>]
正如保羅所說,循環可以用weakref
破:
>>> import weakref
>>> a = NoDel(); b = WithDel()
>>> a.other = weakref.ref(b)
>>> b.other = a # could also be a weakref
然後當b
參考WithDel
目標丟失,它將被刪除,儘管週期:
>>> b = None
deleting WithDel object at 4299656848
>>> a.other
<weakref at 0x10045b9f0; dead>
哦,objgraph會有幫助indicated the problematic __del__
method like this
- 1. 如何處理像A1,A2,...這樣的循環變量?在R
- 2. 是否可以處理這樣的URL
- 3. Python - 這個循環是否正確?
- 4. 是否有像PeekMessage這樣的函數不處理消息?
- 5. 是否有可能使JavaScript中的循環像批處理文件中的循環一樣工作?
- 6. For循環對象引用,而GC
- 7. JAVA - 處理循環引用的JSON庫
- 8. python多處理for循環
- 9. C++圖像處理循環
- 10. 是否有Ruby-Way™來處理這種循環?
- 11. 使用While循環的Python多處理?
- 12. 用於比較的Python處理循環
- 13. c/Python這樣的循環等價嗎?
- 14. 的Python我想這樣做,而循環
- 15. DataContractJsonSerializer可以處理循環引用嗎?
- 16. 處理通知包括循環引用
- 17. Windows批處理循環。用雙引號
- 18. WcfTestClient.exe無法處理循環引用?
- 19. 對for循環使用多處理,Python
- 20. python中的引用循環是什麼?
- 21. 比較像這樣在foreach循環
- 22. 這是什麼樣的for循環?
- 23. `gc`是否像`__del__`一樣對待Cython的`__dealloc__`?
- 24. For循環的Python多處理
- 25. 處理循環
- 26. python中的循環引用
- 27. Ruby是否支持像PHP這樣的var引用?
- 28. 爲什麼Swift不會自動處理循環引用(強引用循環)
- 29. 像Python字典一樣循環Java HashMap?
- 30. 如何處理這個循環?
相關:https://stackoverflow.com/ q/15974561/1959808 –