前言
本文將介紹幾種垃圾回收算法的思想,以及其發展過程。以下共四種垃圾回收算法。
一、標記—清除算法
這個算法是最基礎的算法,算法分爲標記和清除兩個階段:
- 首先標記出所有需要回收的對象
- 在標記完成後統計回收所有標記的對象
此算法有兩個不足:
- 效率問題:標記和清除的效率都不高。
- 空間碎片問題:會產生大量的不連續的內存碎片。
二、複製算法
爲了解決效率的問題,複製算法出現了。
它將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。
當一塊內存用完了,就將還存活着的對象複製到另外一塊上面。
然後把已使用過的內存空間一次清理掉。
這個算法簡單,但是內存縮小爲了原來的一半,未免太高了一點。
IBM公司的專門研究表明,新生代中的對象98%是朝生夕死的,所以並不需要按照1:1的比例來劃分內存空間。
而是將內存劃分爲一塊較大的Eden空間和兩塊 較小的Survivor空間。但是我們沒有辦法保證Survivor空間是夠用的,比如存活的對象已經大於Survivor空間了,這時候就需要依賴其他內存,也就是老年代進行分配擔保。
三、標記—整理算法
複製算法在對象存活率較高時,就要進行較多的複製操作,效率會變低。
根據老年代的特點,對象存活率較高,且沒有額外的空間對他進行分配擔保,出現了標記—整理算法。
與標記—清除算法不一樣的是,標記後的後續步驟不是直接對可回收對象進行清理,而是讓所有存活對象都向一端移動,然後直接清理掉端邊界以外的內存。
四、分代收集算法
當前的商業虛擬機的垃圾收集都是採用的分代收集算法。
它不是什麼新的算法,只是根據Java堆中新生代與老年代的特點,各自採用適合他們的算法。
新生代中,每次垃圾收集時都發現有大批對象死去,只有少量存活,那就採用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。
老年代中因爲對象存活率高,沒有額外空間進行分配擔保,就必須使用標記—清理或者標記—整理算來進行回收。
總結
垃圾收集算法分爲四大類:
- 標記—清除算法:最原始的算法。
- 複製算法:解決空間碎片的問題,適合新生代使用。
- 標記—整理算法:適合老年代使用的垃圾收集算法。
- 分代收集算法:分代採取不同的算法進行回收。