垃圾收集演算法——複製演算法
複製演算法的出現,解決了效率問題,它將可用記憶體按容量劃分為大小相等的兩塊,每次只是用其中的一塊。當這一塊記憶體用完了,就將
還存活著的物件複製到另外一塊上面,然後再把已使用過的記憶體空間一次清理掉。這樣使得每次都是對整個半區進行記憶體回收,記憶體分配時
也就不用考慮記憶體碎片等複雜情況,只要一動堆頂指標,按順序分配記憶體即可,實現簡單,執行高效。
只是這種演算法的代價是將記憶體縮小為了原來的一半,未免太高了點。
複製演算法的執行過程如下圖:
現在的商業虛擬機器都採用複製演算法來回收新生代,IBM公司的專門研究表明,新生代中的物件98%是“朝生夕死”的,所以並不需要按照1:1的
比例來劃分記憶體空間。
堆記憶體中的新生代分為一塊較大的Eden空間和兩塊較小的Survivor空間,詳情請看——JVM記憶體結構/JVM執行時資料區,以及堆記憶體的劃分
每次使用Eden和其中一塊From Survivor,當回收時,將Eden和From Survivor中還存活著的物件一次性地複製到另外一塊To Survivor空間上,最
後清理掉Eden和剛才用過的From Survivor空間。
HotSpot虛擬機器預設Eden:From Survivor:To Survivor = 8:1:1 ,也就是每次新生代中可用記憶體空間為整個新生代容量的90%(80%+10%),
只有10%的記憶體會被“浪費”。當然,98%的物件可回收只是一般場景下的資料,我們沒有辦法保證每次回收都只有不多於10%的物件存活,當To
Survivor空間不夠用時,需要依賴其它記憶體(這裡指老年代)進行分配擔保(Handle Promotion)。
聽過某司的一個面試題,為什麼新生代中Eden:From Survivor:To Survivor是8:1:1,就可以用上面的內容來解釋。