Java虛擬機知識整理——垃圾清理

經過一定的判斷後,虛擬機認定一些對象是垃圾,這也只是判斷而已。需要一個“清潔工”去把已經是垃圾的對象進行回收。回收的方法很多,這裏說的是幾種算法思想。

標記——清除算法

如同算法的名字一樣,算法分爲“標記”和“清除”兩個階段:首先標記出所有需要回收的對象,在標記完成後同意回收所有被標記的對象,它的標記過程就是之前一篇中所說的判斷對象是否是垃圾的過程。
這個算法是最基礎的手機算法,是因爲後續的收集算法都是基於這種思路並對其不足進行改進而得到大。它的主要不足有兩個:一是效率問題,標記和清楚兩個過程的效率都不高;另一個是空間問題,標記清楚後會產生大量不連續的內存碎片,內存碎片會單隻以後在程序運行過程中需要分配較大對象時,無法找到足夠的連續內存而不得不提前觸發另一次垃圾手機動作。

複製算法

爲了解決效率問題,複製算法出現了,它將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。當這一塊的內存用完了,就將還存活這的對象複製到另一塊上面,再把之前使用過的空間一次性清理掉。
這樣使得每次都是對整個搬去進行內存回收,內存分配時也不用考慮內存碎片等複雜情況,值要移動堆頂指針,按順序分配內存即可。實現簡單,運行高效。只是這種算法的代價是將內存縮小爲了原來的一般,未免太高了一點。

標記——整理算法

算法標記,清理的時候讓所有存活的對象都向一段移動,然後直接清理掉邊界以外的內存。
這個算法解決了內存空間的問題,但是執行的時間會變得更多,比較適合頻率比較低的垃圾收集。

分代收集算法

當前商業虛擬機的垃圾手機都採用“分代收集”算法,這種算法沒有新的算法思想,只是根據對象存活週期的不同將內存劃分爲幾塊,一般是把Java堆分爲新生代和老年帶,這樣就可以根據各個年代的特點採用最適當的收集算法。在新生代中,每次垃圾收集時都會發現有大批對象死去,只有少量存活,那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。而老年代中因爲對象存活率高、沒有額外空間對它進行分配擔保,就必須採用“標記——清理”或者“標記——整理”算法來進行回收。

高技巧的“清潔工”工作

Java的有專門負責清理的線程來執行垃圾標記和收集的工作,可以看做是Java的“清潔工”他的工作比一般的清潔工工作難度要高的多,必須要運用實現了這些算法思想的算法來執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章