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