每個Python實現有不同的垃圾收集機制。通用答案是「是的,如果它是垃圾,它應該被垃圾收集。」但是你可能想要比這更具體的東西。
在CPython中,垃圾回收使用refcounting和循環收集器。如果一個對象的refcount降到0,它就會被清理乾淨。但在你的情況下,當你的列表的所有外部引用消失時,仍然會有內部引用,所以本身的refcount不能解決你的問題。這就是循環收集器的用途。
假設您的節點沒有__del__
方法,並且您沒有(直接或間接)禁用「補充垃圾回收」(默認情況下爲啓用),循環收集器將檢測到您的節點都相互引用,但沒有別的東西指向他們,並清理它。 (這可能需要兩道,因爲它使用了代系統)。
可以使用gc
模塊來顯式運行,而不是等待它的循環收集器(gc.collect()
),或檢查它在做什麼。例如,如果你這樣做:
gc.collect()
oldcounts = gc.get_counts()
del last_reference_to_list
gc.collect()
newcounts = gc.get_counts()
print(oldcounts, newcounts)
...你應該能夠告訴(不完美的可靠性,但不夠好,學習和測試目的),你的節點都走了。
如果你的節點做什麼有__del__
方法呢?然後你必須給GC一些幫助。你需要做的是打破任何包含__del__
方法的對象的循環。最明顯的方式做到這一點,如果你沒有任何節點共享列表之間,是剛剛走列表和del
前進後退指針。 (從技術上說,你只需要del
一個或另一個,但你不妨做兩個。)如果您需要在節點上的__del__
方法,你可能需要一個在頂級dl_list
(或tree_node
或不管它是什麼擁有這些),所以這是一個明顯的地方。
當然,如果你不需要__del__
方法,有一種更簡單的解決方案:剛剛擺脫它。
最後一個可能性是使用weakref
的反向鏈接,但對於正向鏈路經常引用。這樣,就沒有可能的循環。但是你必須小心地添加和刪除節點,以確保你永遠不會暫時離開節點,只有一個弱的參考。
如果您使用Jython或IronPython的,垃圾收集與基礎運行時(JVM或.NET),所以你必須閱讀相應的文檔。
PyPy有它自己的垃圾收集器(實際上,可以選擇不同的選項),您可以閱讀關於here的信息。
如果您使用的是不太常見的實現,應該有類似的文檔可用。
只要你沒有參考你的程序中的任何節點,它應該GC作爲無法訪問...(afaik這隻適用於cython)我也認爲它只會gc,如果你還沒有實現__del__方法(見其他評論的回答) –
是的,最終。但是,如果你需要對垃圾收集進行細粒度控制,我會推薦使用更低級的語言,或者至少是Python的gc庫。 – vroomfondel