G1回收器介绍
G1回收器介紹
Garbage-First (G1)垃圾回收器適用于“CPU多核、大內(nèi)存”的服務(wù)器。它嘗試以高概率滿足垃圾收集(GC)暫停時(shí)間目標(biāo),同時(shí)實(shí)現(xiàn)高吞吐量?。
G1回收器將heap分成一組大小相等的region(大約2000個(gè)),每個(gè)region的大小固定在1~32MB(必須為2的冪數(shù))。每個(gè)region的內(nèi)存是物理連續(xù)的,不同的region內(nèi)存物理地址不一定連續(xù),但是同generation的多個(gè)region是邏輯連續(xù)的。 這就是G1“區(qū)域化”。
一組region被邏輯劃分成“young generation(含eden區(qū)、survivor區(qū))”、“old generation(含old region,humongous region”。young generation和old generation的內(nèi)存地址不是固定不變的,會(huì)應(yīng)用的運(yùn)行,由jvm在Xmx范圍動(dòng)態(tài)調(diào)整。
注意:G1中沒(méi)有survivor0 和 survivor1之分,只有一個(gè),大小是動(dòng)態(tài)分配的。
什么是RSets?
每個(gè)Region初始化時(shí),會(huì)初始化一個(gè)remembered set(已記憶集合),該集合用來(lái)記錄并跟蹤其它Region指向該Region中對(duì)象的引用。
如下:Region1和Region3中有對(duì)象引用了Region2的對(duì)象,則在Region2的Rset中記錄了這些引用。
在垃圾回收時(shí),根據(jù)Rsets即可知道一個(gè)region中的對(duì)象被哪些region引用,這樣可以避免掃描整個(gè)堆來(lái)找到可以回收的垃圾。
什么是Csets?
垃圾回收器計(jì)劃回收的region集合。
YoungGC過(guò)程?
步驟1.? 選擇收集集合(Collection Set),G1會(huì)在遵循用戶設(shè)置的GC暫停時(shí)間上限的基礎(chǔ)上,選擇一個(gè)最大年輕代region數(shù),將這個(gè)數(shù)量的所有年輕代區(qū)域作為收集集合。
步驟2.? 根處理(Root Scanning),接下來(lái),需要從GC ROOTS遍歷,查找從ROOTS直達(dá)到收集集合的對(duì)象,移動(dòng)他們到Survivor區(qū)域的同時(shí)將他們的引用對(duì)象加入標(biāo)記棧
步驟3.? RSet掃描(Scan RS),將RSet作為ROOTS遍歷,查找可直達(dá)到收集集合的對(duì)象,移動(dòng)他們到Survivor區(qū)域的同時(shí)將他們的引用對(duì)象加入標(biāo)記棧
步驟4.? 移動(dòng)(Evacuation/Object Copy),遍歷上面的標(biāo)記棧,將棧內(nèi)的所有所有的對(duì)象移動(dòng)至Survivor區(qū)域(其實(shí)說(shuō)是移動(dòng),本質(zhì)上還是復(fù)制)
注意:YoungGC過(guò)程中,存活對(duì)象copy到survivor區(qū)或者old區(qū)的過(guò)程是需要STW的。
eden區(qū)和survivor區(qū)的大小是動(dòng)態(tài)計(jì)算的,可能會(huì)一直在變動(dòng)過(guò)程中。
觸發(fā)條件:當(dāng)JVM無(wú)法將新對(duì)象分配到eden區(qū)域時(shí),會(huì)觸發(fā)年輕代的垃圾回收(年輕代垃圾回收是完全暫停的,雖然部分過(guò)程是并行,但暫停和并行并不沖突)。也會(huì)稱為“evacuation pause”
G1回收器回收old generation的標(biāo)記過(guò)程
- 初始標(biāo)記階段(Initial Mark):需要STW。 對(duì)于G1,該過(guò)程依附在一個(gè)正常的Young GC上。 標(biāo)記survivor區(qū)域的GCroots,這些區(qū)域可能引用old generation中的對(duì)象。
- GCroots掃描階段(root scan):掃描initial mark階段標(biāo)記出的GC roots關(guān)聯(lián)的survivor區(qū)的對(duì)象,以及這些對(duì)象引用old generation的對(duì)象。標(biāo)記出引用的對(duì)象。
- 并發(fā)標(biāo)記階段(concurrent mark):在整個(gè)heap中標(biāo)記存活對(duì)象(live object)。該過(guò)程和應(yīng)用線程并發(fā)執(zhí)行不需要STW,也可以被young GC打斷。
- 重新標(biāo)記階段(remark):需要STW。使用'SATB[snapshot-at-the-beginning]'算法再次標(biāo)記前述幾個(gè)過(guò)程中斷開(kāi)的引用,避免漏標(biāo)。? <解決了CMS可能的垃圾漏標(biāo)問(wèn)題>
- 清理階段(cleanup):
- 統(tǒng)計(jì)存活對(duì)象,根據(jù)設(shè)定的目標(biāo)停頓時(shí)間,確定要回收的region。該過(guò)程需要STW
- 清空Remembered Sets("Rsets")。該過(guò)程需要STW
- 重置空的region,并將其加到空白列表中。該過(guò)程是concurrent的。
什么是MixedGC?
mixedGC,即混合GC,針對(duì)年輕代和老年代都進(jìn)行垃圾回收。mixedGC是G1垃圾回收器中特有的概念。
觸發(fā)條件:一旦老年代占據(jù)堆內(nèi)存的 45%(-XX:InitiatingHeapOccupancyPercent:設(shè)置觸發(fā)標(biāo)記周期的 Java 堆占用率閾值,默認(rèn)值是 45%。),就要觸發(fā) Mixed GC的標(biāo)記周期。
什么是full gc?
對(duì)整個(gè)堆進(jìn)行回收,包括新生代,老年代、metaspace等。
觸發(fā)條件:當(dāng)mixedGC回收內(nèi)存的速度無(wú)法跟上內(nèi)存分配的速度,導(dǎo)致老年代也滿了,就會(huì)進(jìn)行Full GC對(duì)整個(gè)堆進(jìn)行回收。G1中的Full GC也而是單線程串行的,而且是全暫停,使用的是標(biāo)記-整理算法,代價(jià)非常高。
G1回收器引入STW的幾種情形?
官方文檔:
- Getting Started with the G1 Garbage Collector
- https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc.html#garbage_first_garbage_collection
- https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#g1_gc_tuning
總結(jié)
- 上一篇: appcan与java_APPCAN学习
- 下一篇: java ssi_快速部署SSI框架