G1垃圾收集器在JDK1.7中投入使用,并作為JDK1.9默認(rèn)的垃圾收集器。
JVM配置開啟G1參數(shù):
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200
一、G1與CMS相比有什么區(qū)別?
1.內(nèi)存碎片
CMS是一款“標(biāo)記--清除”算法實現(xiàn)的收集器,容易出現(xiàn)大量空間碎片
G1通過將內(nèi)存空間分成區(qū)域(Region)的方式避免內(nèi)存碎片問題。 整體是標(biāo)記整理,Region之間通過復(fù)制算法,都不會產(chǎn)生內(nèi)存碎片
2.停頓時間
G1可以通過設(shè)置預(yù)期停頓時間(Pause Time)來控制垃圾收集時間。
3.回收范圍
G1能同時回收老年代和新生代,CMS是老年代收集器。
4.內(nèi)存劃分
Eden, Survivor, Old區(qū)不再固定、在內(nèi)存使用效率上來說更靈活
二、堆存儲結(jié)構(gòu)
1.以往的垃圾回收算法堆結(jié)構(gòu)

新生代:eden space + 2個survivor
老年代:old space
持久代:1.8之前的perm space
元空間:1.8之后的metaspace
這些space必須是地址連續(xù)的空間。
2.G1垃圾回收算法堆結(jié)構(gòu)
堆內(nèi)存被劃分為多個大小相等的內(nèi)存塊(Region),每個Region是邏輯連續(xù)的一段內(nèi)存

E:eden區(qū)
S:serviver區(qū)
O:old區(qū)
H:humongous(巨型對象)
當(dāng)新建對象大小超過Region大小一半時,直接在新的一個或多個連續(xù)Region中分配,并標(biāo)記為H。
Region
堆內(nèi)存中一個Region的大小可以通過-XX:G1HeapRegionSize參數(shù)指定,大小區(qū)間只能是1M、2M、4M、8M、16M和32M,總之是2的冪次方,如果G1HeapRegionSize為默認(rèn)值,則在堆初始化時計算Region的實際大小。
默認(rèn)把堆內(nèi)存按照2048份均分,最后得到一個合理的大小。
三、GC模式
young gc、mixed gc 和 full gc,在不同的條件下被觸發(fā).
young gc
發(fā)生條件:
1.年輕代
2.除了巨型對象外的一般對象
3.eden region 被耗盡無法申請到內(nèi)存
young gc結(jié)果:
活躍對象被拷貝到S區(qū)或者晉升到O區(qū)
young gc JVM參數(shù):
-XX:MaxGCPauseMillis 設(shè)置G1收集過程目標(biāo)時間,默認(rèn)值200ms
-XX:G1NewSizePercent 新生代最小值,默認(rèn)值5%
-XX:G1MaxNewSizePercent 新生代最大值,默認(rèn)值60%
mixed gc:
發(fā)生條件:
晉升到O區(qū)的對象越來越多,為了避免內(nèi)存耗盡。當(dāng)達(dá)到一定的閥值觸發(fā),相關(guān)JVM參數(shù):
XX:InitiatingHeapOccupancyPercent=60
當(dāng)老年代大小占整個堆大小百分比達(dá)到該閾值時,會觸發(fā)一次mixed gc
類似CMS:
-XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly
young gc結(jié)果:
回收整個Y區(qū),和一部分O區(qū)??梢赃x擇哪些old region進(jìn)行收集,從而可以對垃圾回收的耗時時間進(jìn)行控制。
mixed gc的執(zhí)行步驟:
1.initial mark:
初始標(biāo)記過程,整個過程STW,標(biāo)記了從GC Root可達(dá)的對象2.concurrent marking:
并發(fā)標(biāo)記過程,整個過程gc collector線程與應(yīng)用線程可以并行執(zhí)行,標(biāo)記出GC Root可達(dá)對象衍生出去的存活對象,并收集各個Region的存活對象信息3.remark:
最終標(biāo)記過程,整個過程STW,標(biāo)記出那些在并發(fā)標(biāo)記過程中遺漏的,或者內(nèi)部引用發(fā)生變化的對象4.clean up:
垃圾清除過程,如果發(fā)現(xiàn)一個Region中沒有存活對象,則把該Region加入到空閑列表中
full gc
如果對象內(nèi)存分配速度過快,mixed gc來不及回收,導(dǎo)致老年代被填滿,就會觸發(fā)一次full gc。
G1的full gc算法就是單線程執(zhí)行的serial old gc,會導(dǎo)致異常長時間的暫停時間,需要進(jìn)行不斷的調(diào)優(yōu),盡可能的避免full gc.