CMS:Concurrent Mark Sweep,以獲取最短回收停頓時間為目標的收集器,基於並發“標記清理”實現。JDK1.7之前的默認垃圾回收算法,並發收集,停頓小。
過程:
1、初始標記:stop-the-world,標記GCRoots直接關聯的對象
2、並發標記:和用戶線程並行執行,標記所有可達對象
3、重新標記:stop-the-world,對並發標記階段用戶線程運行產生的垃圾對象進行標記修正
4、並發清理:清理垃圾對象,和用戶線程同時執行
5、並發重置:重置CMS收集器的數據結構
優點:
並發,低停頓
缺點:
1、對CPU非常敏感:在並發階段雖然不會導致用戶線程停頓,但是會因為占用了一部分線程使應用程序變慢
2、無法處理浮動垃圾:在最后一步並發清理過程中,用戶線程執行也會產生垃圾,但是這部分垃圾是在標記之后,所以只有等到下一次gc的時候清理掉,這部分垃圾叫浮動垃圾
3、CMS使用“標記-清理”法會產生大量的空間碎片,當碎片過多,將會給大對象空間的分配帶來很大的麻煩,往往會出現老年代還有很大的空間但無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次FullGC,為了解決這個問題CMS提供了一個開關參數,用於在CMS頂不住,要進行FullGC時開啟內存碎片的合並整理過程,但是內存整理的過程是無法並發的,空間碎片沒有了但是停頓時間變長了
G1:Garbage First,是一款面向服務端應用的垃圾收集器。
特點:
1、G1垃圾收集器將整個 JVM 內存分為多個大小相等的region,年輕代和老年代邏輯分區 。
2、G1 是 Java9 以后的默認垃圾回收器
3、G1 在整體上使用標記整理算法,局部使用復制算法
4、G1 的每個 Region 大小在 1-32M 之間,可以通過-XX:G1HeapRegionSize=n 指定區大小。
5、總的 Region 個數最大可以存在 2048 個,即heap最大能夠達到32M*2048=64G
6、0.5<obj<1,那么放到old區,old標記為H 1<obj<n,連續的n個region,作為H
過程:
初始標記:標記出GCRoot對象,以及GCRoot所在的Region(RootRegion)
Root Region Scanning:掃表整個old的Region
並發標記:並發追溯標記,進行GCRootsTracing的過程
最終標記:修正並發標記期間,因程序運行導致標記發生變化的那一部分對象
清理回收:根據時間來進行價值最大化的回收,重置rset
ZGC:Z Garbage Collector 垃圾收回器,是一種可伸縮的低延遲垃圾收集器。
邏輯上一次ZGC分為Mark(標記)、Relocate(遷移)、Remap(重映射)三個階段
- Mark: 所有活的對象都被記錄在對應Page的Livemap(活對象表,bitmap實現)中,以及對象的Reference(引用)都改成已標記(Marked0或Marked1)狀態
- Relocate: 根據頁面中活對象占用的大小選出的一組Page,將其中的活對象都復制到新的Page,並在額外的forward table(轉移表)中記錄對象原地址和新地址對應關系
- Remap: 所有Relocated的活對象的引用都重新指向了新的正確的地址
實現上,由於想要將所有引用都修正過來需要跟Mark階段一樣遍歷整個對象圖,所以這次的Remap會與下一次的Remark階段合並。所以在GC的實現上是2個階段,即Mark&Remap階段和Relocate階段
使用場景對比:
G1適合8/16G以上的內存使用,原因在於G1 rescan更快,清除垃圾時雖然是stop the world但是可控,
CMS雖然是並發但是不可控,大塊內存要回收會影響到應用程序的性能。
另外由於G1在清理垃圾時使用STW,所以可以采用標記整理算法,沒有內存碎片問題
ZGC作為下一代垃圾回收器,性能非常優秀。ZGC垃圾回收過程幾乎全部是並發,實際STW停頓時間極短,不到10ms。這得益於其采用的着色指針和讀屏障技術。