JVM虛擬機垃圾回收CMS和G1的區別


這是我開通博客園的第一篇文章,有錯誤的地方,請大家指正,之所以開通博客園,是受到以為學長的影響,看着他在博客園的博客,我知道寫博客不僅是自我復習的一個過程,也是一個和別人溝通的窗口,所以我打算向學長學習,以后多記錄博客,加深知識點的印象。

CMS和G1的區別是我最近在面試過程中經常被問到的一個問題,雖然能答出幾點出來,但是自己並不太滿意,網上關於兩者的對比也沒有特別完善的文章,於是打算記錄下這邊文章

首先我把答案給出來,然后再去分析為什么會這樣

 

CMS

G1

JDK版本

1.6以上

1.7以上

回收算法

標記——清除

標記——整理

運行環境

針對70G以內的堆內存

可針好幾百G的大內存

回收區域

老年代

新生代和老年代

內存布局

傳統連續的新生代和老年代區域

Region(將新生代和老年代切分成Region,默認一個Region 1 M,默認2048塊)

浮動垃圾

內存碎片

全堆掃描

回收時間可控

對象進入老年代的年齡

6

15

空間動態調整

是(新生代5%-60%動態調整,一般不需求指定)

調優參數

多(近百個)

少(十幾個)

 

1、CMS

CMS(Concurrent Mark Sweep),我們可以輕易地從命名上看出,它是一個並發的,然后是基於標記——清理的垃圾回收器,它清理垃圾的步驟大致分為四步:

  1. 初始標記
  2. 並發標記
  3. 重新標記
  4. 並發清理

 

 

 (圖片是出自網上,如有侵犯請聯系我,謝謝)

初始標記只要是找到GC Roots,所以是一個很快的過程,並發標記和用戶線程一起,通過GC Roots找到存活的對象,重新標記主要是修復在並發標記階段的發生了改變的對象,這個階段會Stop the World;

並發清理則是保留上一步驟標記出的存活對象,清理掉其他對象,正因為采用並發清理,所以在清理的過程中用戶線程又會產生垃圾,而導致浮動垃圾,只能通過下次垃圾回收進行處理;

因為cms采用的是標記清理,所以會導致內存空間不連續,從而產生內存碎片

此處要清楚,CMS的垃圾回收的內存模型還是以我們常用的新生代,老年代的結構,如下圖所示:

2.G1

G1(Garbage-First),以分而治之的思想將堆內存分為若干個等大的Region塊,雖然還是保留了新生代,老年代的概念,但是G1主要是以Region為單位進行垃圾回收,G1的分塊大體結果如下圖所示:

 

G1垃圾回收器的它清理垃圾的步驟大致分為四步:

  1. 初始標記
  2. 並發標記
  3. 最終標記
  4. 復制回收

初始標記和並發標記和CMS的過程是差不多的,最后的篩選回收會首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓時間來制定回收計划

因為采用的標記——整理的算法,所以不會產生內存碎片,最終的回收是STW的,所以也不會有浮動垃圾,Region的區域大小是固定的,所以回收Region的時間也是可控的

同時G1 使用了Remembered Set來避免全堆掃描,G1中每個Region都有一個與之對應的RememberedSet ,在各個 Region 上記錄自家的對象被外面對象引用的情況。當進行內存回收時,在GC根節點的枚舉范圍中加入RememberedSet 即可保證不對全堆掃描也不會有遺漏。

以上就是CMS和G1的對比過程,如果面試中能回答出這些內容應該就能博得面試官一笑,盜圖可恥,匿了


免責聲明!

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



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