JVM系列:(十一)GC演算法與使用場景
原文連結: JVM系列:(十一)GC演算法與使用場景
一 標記-清除演算法
該演算法的工作過程和其名字一樣,分為標記和清除兩個階段;首先標記GC Roots不可達的物件為待回收狀態,在標記完成後統一回收所有被標記的物件。

標記-清除演算法
1.1 不足之處
- 效率不高,標記和清除兩個階段的效率都不高;
- 空間零碎,標記清除之後會產生大量不連續的記憶體碎片,空間碎片太多可能導致後面無法分配大物件,然後提前觸發垃圾回收動作;
二 複製演算法
複製演算法是為了解決標記-清楚演算法的低效率問題而設計的。它將記憶體劃分為大小相等的兩塊,每次只使用其中的一塊,當這一塊用完後,再將還存活的物件複製到另一塊上,最後將已使用過的記憶體空間一次清理掉。
這樣每次都是對整個半區進行回收,回收完後也不會出現記憶體碎片等情況,空白半區只需要按順序分配記憶體即可,實現簡單,執行高效。

複製演算法
2.1 不足之處
- 將可用記憶體縮小為原來的一半,記憶體過於浪費;
- 物件存活率較高時,需要複製的物件較多,效率低;
三 標記-整理演算法
針對JVM堆記憶體中的老齡代物件的存活率高,佔用記憶體大等特點,有人提出了標記-整理演算法。該演算法類似於標記-清除演算法,但後續步驟不是對可回收物件進行清理,而是讓所有存活的物件都向一端移動,然後直接清理掉端邊界以外的記憶體。

標記-整理演算法
3.1 不足之處
- 對於前面可回收的物件,需要移動後面還存活物件;
四 分代收集演算法
將記憶體分為兩大塊,新生代和老齡代,根據物件存活週期各個年代的特點將物件存放在不同塊中,針對不同塊採用最適當的收集演算法進行垃圾回收。
在新生代中,每次垃圾回收時都發現大批物件死去,只有少量存活,那就選用複製演算法,只需要付出少量存活物件的複製成本就可以完成收集;而老齡代中因為物件存活率高,沒有額外空間對它進行分配擔保,就必須使用“標記-清除”或者“標記-整理”演算法來進行回收;
五 使用場景
我們把上一章說的JVM記憶體分配的堆記憶體分配的圖拿過來,再結合這章的垃圾收集演算法,具體說一下垃圾收集演算法在堆記憶體中的具體使用。

JVM堆記憶體分配
上圖可知,從整體上看。
JVM堆記憶體 = 新生代 + 老齡代;
新生代 = 伊甸園 + 交換區;
交換區 = from + to;
- 新生代+老齡代:分代收集演算法;
- 老齡代:一般採用“標記-整理”或“標記-清除”演算法;
- 伊甸園+from或to:複製演算法;

掃碼關注有驚喜