CMS和G1的區別,以及Parallel


CMS:以獲取最短回收停頓時間為目標的收集器,基於並發“標記清理”實現

過程:

1、初始標記:獨占PUC,僅標記GCroots能直接關聯的對象

2、並發標記:可以和用戶線程並行執行,標記所有可達對象

3、重新標記:獨占CPU(STW),對並發標記階段用戶線程運行產生的垃圾對象進行標記修正

4、並發清理:可以和用戶線程並行執行,清理垃圾

優點:

並發,低停頓

缺點:

1、對CPU非常敏感:在並發階段雖然不會導致用戶線程停頓,但是會因為占用了一部分線程使應用程序變慢

2、無法處理浮動垃圾:在最后一步並發清理過程中,用戶縣城執行也會產生垃圾,但是這部分垃圾是在標記之后,所以只有等到下一次gc的時候清理掉,這部分垃圾叫浮動垃圾

3、CMS使用“標記-清理”法會產生大量的空間碎片,當碎片過多,將會給大對象空間的分配帶來很大的麻煩,往往會出現老年代還有很大的空間但無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次FullGC,為了解決這個問題CMS提供了一個開關參數,用於在CMS頂不住,要進行FullGC時開啟內存碎片的合並整理過程,但是內存整理的過程是無法並發的,空間碎片沒有了但是停頓時間變長了

CMS 出現FullGC的原因:

1、年輕帶晉升到老年帶沒有足夠的連續空間,很有可能是內存碎片導致的

2、在並發過程中JVM覺得在並發過程結束之前堆就會滿,需要提前觸發FullGC

 

G1:是一款面向服務端應用的垃圾收集器

特點:

1、並行於並發:G1能充分利用CPU、多核環境下的硬件優勢,使用多個CPU(CPU或者CPU核心)來縮短stop-The-World停頓時間。部分其他收集器原本需要停頓Java線程執行的GC動作,G1收集器仍然可以通過並發的方式讓java程序繼續執行。

2、分代收集:分代概念在G1中依然得以保留。雖然G1可以不需要其它收集器配合就能獨立管理整個GC堆,但它能夠采用不同的方式去處理新創建的對象和已經存活了一段時間、熬過多次GC的舊對象以獲取更好的收集效果。也就是說G1可以自己管理新生代和老年代了。

3、空間整合:由於G1使用了獨立區域(Region)概念,G1從整體來看是基於“標記-整理”算法實現收集,從局部(兩個Region)上來看是基於“復制”算法實現的,但無論如何,這兩種算法都意味着G1運作期間不會產生內存空間碎片。

4、可預測的停頓:這是G1相對於CMS的另一大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用這明確指定一個長度為M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒。

 

 

與其它收集器相比,G1變化較大的是它將整個Java堆划分為多個大小相等的獨立區域(Region),雖然還保留了新生代和來年代的概念,但新生代和老年代不再是物理隔離的了它們都是一部分Region(不需要連續)的集合。同時,為了避免全堆掃描,G1使用了Remembered Set來管理相關的對象引用信息。當進行內存回收時,在GC根節點的枚舉范圍中加入Remembered Set即可保證不對全堆掃描也不會有遺漏了。

 

如果不計算維護Remembered Set的操作,G1收集器的運作大致可划分為以下幾個步驟:

1、初始標記(Initial Making)

2、並發標記(Concurrent Marking)

3、最終標記(Final Marking)

4、篩選回收(Live Data Counting and Evacuation)

看上去跟CMS收集器的運作過程有幾分相似,不過確實也這樣。初始階段僅僅只是標記一下GC Roots能直接關聯到的對象,並且修改TAMS(Next Top Mark Start)的值,讓下一階段用戶程序並發運行時,能在正確可以用的Region中創建新對象,這個階段需要停頓線程,但耗時很短。並發標記階段是從GC Roots開始對堆中對象進行可達性分析,找出存活對象,這一階段耗時較長但能與用戶線程並發運行。而最終標記階段需要吧Remembered Set Logs的數據合並到Remembered Set中,這階段需要停頓線程,但可並行執行。最后篩選回收階段首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓時間來制定回收計划,這一過程同樣是需要停頓線程的,但Sun公司透露這個階段其實也可以做到並發,但考慮到停頓線程將大幅度提高收集效率,所以選擇停頓。下圖為G1收集器運行示意圖:

 G1 GC和CMS GC相比的優缺點?

G1 GC 這是一種兼顧吞吐量和停頓時間的 GC 實現,是 Oracle JDK 9 以后的默認 GC 選
項。G1 可以直觀的設定停頓時間的目標,相比於 CMS GC,G1 未必能做到 CMS 在最好情
況下的延時停頓,但是最差情況要好很多。


G1 GC 仍然存在着年代的概念,但是其內存結構並不是簡單的條帶式划分,而是類似棋盤的
一個個 region。Region 之間是復制算法,但整體上實際可看作是標記 - 整理(Mark-
Compact)算法,可以有效地避免內存碎片,尤其是當 Java 堆非常大的時候,G1 的優勢更
加明顯。

 

Parrallel GC,(jdk8默認GC)在早期 JDK 8 等版本中,它是 server 模式 JVM 的默認 GC 選擇,也被稱作
是吞吐量優先的 GC。

它的算法和 Serial GC(最早的GC,單線程) 比較相似(從年代的角度,通常將其老年代實現單獨稱作 Serial Old,它采用了標記 - 整理(Mark,Compact)算法,區別於新生代的復制算法),盡管實現要復雜的多,其特點是新生
代和老年代 GC 都是並行進行的,在常見的服務器環境中更加高效。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM