java - jvm垃圾回收 - python垃圾回收




為什麼Java和Python垃圾收集方法有所不同? (6)

我認為IBM的文章“ Java理論與實踐:垃圾收集的簡史 ”應該有助於解釋一些問題。

Python使用引用計數方法來處理對象的生命週期。 所以沒有更多使用的對象將被立即銷毀。

但是,在Java中,GC(垃圾回收器)會破壞在特定時間不再使用的對象。

為什麼Java選擇這個策略,從中得到什麼好處呢?

這比Python方法更好嗎?


最新的Sun Java VM實際上有多個你可以調整的GC算法。 Java VM規範故意忽略了指定實際的GC行為,以允許針對不同VM的不同(和多個)GC算法。

例如,對於所有不喜歡默認Sun Java VM GC行為的“停止世界”方法的人來說,都有像IBM的WebSphere Real Time這樣的VM,它允許實時應用程序在Java上運行。

由於Java VM規範是公開可用的,所以從理論上講沒有任何人阻止任何人使用CPython的GC算法來實現Java VM。


引用計數在多線程環境中特別難以有效地執行。 我不知道如何進行硬件輔助交易或類似的(目前)不尋常的原子指令。

引用計數很容易實現。 JVM有大量資金投入競爭實施,所以他們實施非常好的解決方案來解決非常棘手的問題並不奇怪。 但是,在JVM上定位自己喜歡的語言變得越來越容易了。


如果您有足夠的內存,垃圾收集比參考計數更快(更省時)。 例如,複製gc遍歷“活”對象並將它們複製到一個新的空間,並且可以通過標記整個內存區域來一步回收所有“死”對象。 如果你有足夠的內存,這是非常有效的。 世代收藏使用“大多數物體年輕化”的知識; 通常只有百分之幾的對象必須被複製。

[這也是gc可以比malloc / free更快的原因]

引用計數比垃圾收集更節省空間,因為它在無法訪問的時刻回收內存。 這是很好的,當你想附加終結器的對象(例如一旦File對象無法訪問關閉文件)。 即使只有百分之幾的內存空閒,引用計數係統也可以工作。 但是在每個指針分配上增加和減少計數器的管理成本花費了大量時間,並且還需要某種垃圾收集來回收週期。

因此,權衡是明確的:如果您必須在內存受限的環境中工作,或者如果您需要精確的終結器,請使用引用計數。 如果你有足夠的內存和需要的速度,使用垃圾收集。


在遊戲後期,但我認為在Python中RC的一個重要的基本原理是它的簡單性。 例如,請參閱Alex Martelli的電子郵件

(我無法找到一個鏈接外的谷歌緩存,電子郵件日期從2005年10月13日在Python列表)。


使用引用計數有一些缺點。 其中提到的最多的是循環引用:假設一個引用B,B引用C和C引用B.如果A將它的引用放到B中,那麼B和C都將具有1的引用計數並且不會被刪除與傳統的參考計數。 CPython(引用計數不是python本身的一部分,但是它的C實現的一部分)通過一個單獨的垃圾回收例程捕獲循環引用,它週期性地運行...

另一個缺點:引用計數可能會使執行速度變慢。 每次一個對像被引用和取消引用時,解釋器/虛擬機必須檢查計數是否已經降到0(然後如果是,則釋放)。 垃圾收集不需要這樣做。

此外,垃圾收集可以在一個單獨的線程完成(雖然可能有點棘手)。 在有很多內存的機器上,以及只能緩慢使用內存的進程中,你可能根本不想做GC! 引用計數在性能方面會有一些缺點...







garbage-collection