本文主要研究下JEP 248: Make G1 the Default Garbage Collectorhtml
java9廢棄了CMS垃圾收集器,並把G1提高爲默認垃圾收集器,替代了原來的吞吐優先的ParallelOldGC
G1相對於以前的垃圾收集器最大的不一樣是引入了Region。G1雖然也是基於分代機制,可是各個generation的空間再也不連續,以下圖:
java
能夠用-XX:G1HeapRegionSize=16m來指定Region Size,注意它必須是2的乘方,範圍在1MB到32MB之間。目標是根據最小的Java堆大小劃分出約2048 個區域.
若是沒有明確指定,則自動根據Heap Size來指定,其對應關係以下:git
Min Heap Size | Region Size |
---|---|
heap < 4GB | 1MB |
4GB <= heap < 8GB | 2MB |
8GB <= heap < 16GB | 4MB |
16GB <= heap < 32GB | 8MB |
32GB <= heap < 64GB | 16MB |
64GB <= heap | 32MB |
巨型對象默認直接會被分配在年老代,可是若是它是一個短時間存在的巨型對象,就會對垃圾收集器形成負面影響。爲了解決這個問題,G1劃分了一個Humongous區,它用來專門存放巨型對象。若是一個H區裝不下一個巨型對象,那麼G1會尋找連續的H分區來存儲。爲了能找到連續的H區,有時候不得不啓動Full GC。
正常的young gc
Minor GC + (# reclaimable Tenured regions / -XX:G1MixedGCCountTarget) regions of Tenured
All regions evacuated,一般Humongous object太多會耗盡空間,致使Full GC
Minor/Mixed + rollback + Full GC
主要分爲:Minor GC,Mixed/Old GCgithub
STW
)Young GC主要是對Eden區進行GC,它在Eden空間不夠時會被觸發。Eden空間的數據移動到Survivor空間中,若是Survivor空間不夠,Eden空間的部分數據會直接晉升到年老代空間。From Survivor區的數據移動到To Survivor區中,也有部分數據晉升到老年代空間中。
其階段主要以下:併發
階段 | 執行動做 |
---|---|
階段1 根掃描 | 靜態和本地對象被掃描 |
階段2 更新RS | 處理dirty card隊列更新RS |
階段3 處理RS | 檢測從年輕代指向年老代的對象 |
階段4 對象拷貝 | 拷貝存活的對象到survivor/old區域 |
階段5 處理引用隊列 | 軟引用,弱引用,虛引用處理 |
STW
)主要是對年老代進行併發標記而後進行GC,其中部分階段涉及到ygc,同時既有ygc及old gc的部分稱爲mixed gc。oracle
併發標記週期(Concurrent Marking Cycle Phases)階段以下:app
階段 | 執行動做 |
---|---|
(1) Initial Mark(Stop the World Event) 初始標記階段 | 在此階段G1 GC對根進行標記。該階段與常規的 (STW) 年輕代垃圾回收密切相關。日誌標記爲Pause Initial Mark (G1 Evacuation Pause). |
(2) Root Region Scanning 根區域掃描階段 | G1 GC在初始標記的存活區掃描對老年代的引用,並標記被引用的對象。該階段與應用程序(非 STW)同時運行,而且只有完成該階段後,才能開始下一次STW年輕代垃圾回收。 |
(3) Concurrent Marking 併發標記階段 | G1 GC在整個堆中查找可訪問的(存活的)對象。該階段與應用程序同時運行,能夠被 STW 年輕代垃圾回收中斷。 |
(4) Remark(Stop the World Event) 從新標記階段 | 該階段是STW回收,幫助完成標記週期。G1 GC清空SATB緩衝區,跟蹤未被訪問的存活對象,並執行引用處理。 |
(5) Copying(Stop the World Event) / Cleanup(Stop the World Event and Concurrent) 拷貝/清理階段 | 在這個最後階段,G1 GC爲了更快進行垃圾回收,會選擇那些存活率低的region進行拷貝,即evacuate或者拷貝存活對象到新的空閒的regions,而後清理回收該region,此時會STW,若是是在年輕代產生的,則日誌標記爲Pause Young (G1 Evacuation Pause),若是年輕代和年老代都進行這個動做,則日誌標記爲Pause Mixed (G1 Evacuation Pause). |
核心的階段主要是Concurrent Marking Phase、Remark Phase、Copying/Cleanup Phase
參數 | 含義 |
---|---|
-XX:G1HeapRegionSize=n | 設置Region大小,並不是最終值 |
-XX:MaxGCPauseMillis=200 | 設置G1收集過程目標時間,默認值200ms,不是硬性條件 |
-XX:G1NewSizePercent=5 | 新生代最小值,默認值5% |
-XX:G1MaxNewSizePercent=60 | 新生代最大值,默認值60% |
-XX:ParallelGCThreads=n | STW期間,並行GC線程數,其值與邏輯處理器的數量相同,最多爲8。若是邏輯處理器不止八個,則將n爲邏輯處理器數的5/8 |
-XX:ConcGCThreads=n | 併發標記階段的並行標記線程數,ParallelGCThreads的 1/4 左右 |
-XX:InitiatingHeapOccupancyPercent=45 | 設置觸發標記週期的Java堆佔用率閾值。默認值是45%。這裏的java堆佔比指的是non_young_capacity_bytes,包括old+humongous |
-XX:G1MixedGCLiveThresholdPercent=65 | 爲混合垃圾回收週期中要包括的舊區域設置佔用率閾值。默認佔用率爲 65% |
-XX:G1HeapWastePercent=10 | 若是可回收百分比小於此值,JVM不會啓動混合垃圾回收週期。默認值是10% |
-XX:G1OldCSetRegionThresholdPercent=10 | 設置混合垃圾回收期間要回收的最大舊區域數。默認值是Java堆的10% |
-XX:G1MixedGCCountTarget=8 | 設置標記週期完成後,對存活數據上限爲 G1MixedGCLIveThresholdPercent 的舊區域執行混合垃圾回收的目標次數。默認8次混合垃圾回收,混合回收的目標是要控制在此目標次數之內 |
-XX:G1ReservePercent=10 | 設置做爲空閒空間的預留內存百分比,以下降目標空間溢出的風險。默認值是10%。增長或減小百分比時,請確保對總的Java 堆調整相同的量 |
避免使用-Xmn選項或-XX:NewRatio等其餘相關選項顯式設置年輕代大小,固定年輕代的大小會禁用掉暫停時間(MaxGCPauseMillis)目標。
簡版使用-Xlog:gc=info,詳細版使用-Xlog:gc*=infoless
[0.317s][info][gc] GC(37) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.511ms [0.324s][info][gc] GC(40) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.709ms
[0.011s][info][gc,heap] Heap region size: 1M [0.012s][info][gc ] Using G1 [0.012s][info][gc,heap,coops] Heap address: 0x00000007bf600000, size: 10 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 [0.170s][info][gc,start ] GC(0) Pause Young (G1 Evacuation Pause) [0.170s][info][gc,task ] GC(0) Using 8 workers of 8 for evacuation [0.172s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.0ms [0.172s][info][gc,phases ] GC(0) Evacuate Collection Set: 1.5ms [0.172s][info][gc,phases ] GC(0) Post Evacuate Collection Set: 0.1ms [0.172s][info][gc,phases ] GC(0) Other: 0.1ms [0.172s][info][gc,heap ] GC(0) Eden regions: 4->0(2) [0.172s][info][gc,heap ] GC(0) Survivor regions: 0->1(1) [0.172s][info][gc,heap ] GC(0) Old regions: 0->1 [0.172s][info][gc,heap ] GC(0) Humongous regions: 0->0 [0.172s][info][gc,metaspace ] GC(0) Metaspace: 5982K->5982K(1056768K) [0.172s][info][gc ] GC(0) Pause Young (G1 Evacuation Pause) 4M->1M(10M) 1.718ms [0.172s][info][gc,cpu ] GC(0) User=0.01s Sys=0.00s Real=0.00s
[0.321s][info][gc] GC(38) Pause Initial Mark (G1 Evacuation Pause) 7M->6M(10M) 0.601ms [0.321s][info][gc] GC(39) Concurrent Cycle [0.324s][info][gc] GC(40) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.709ms [0.326s][info][gc] GC(39) Pause Remark 7M->7M(10M) 0.623ms [0.326s][info][gc] GC(39) Pause Cleanup 7M->7M(10M) 0.104ms [0.326s][info][gc] GC(39) Concurrent Cycle 5.398ms [0.327s][info][gc] GC(41) Pause Young (G1 Evacuation Pause) 7M->6M(10M) 0.512ms [0.331s][info][gc] GC(42) To-space exhausted [0.331s][info][gc] GC(42) Pause Mixed (G1 Evacuation Pause) 7M->7M(10M) 1.190ms [0.334s][info][gc] GC(43) Pause Initial Mark (G1 Evacuation Pause) 8M->7M(10M) 0.637ms [0.334s][info][gc] GC(44) Concurrent Cycle [0.338s][info][gc] GC(45) Pause Young (G1 Evacuation Pause) 8M->7M(10M) 0.553ms [0.340s][info][gc] GC(44) Pause Remark 8M->8M(10M) 0.582ms [0.341s][info][gc] GC(44) Pause Cleanup 8M->8M(10M) 0.100ms [0.341s][info][gc] GC(44) Concurrent Cycle 6.195ms
[0.942s][info][gc,start ] GC(192) Pause Initial Mark (G1 Evacuation Pause) [0.942s][info][gc,task ] GC(192) Using 8 workers of 8 for evacuation [0.942s][info][gc,phases ] GC(192) Pre Evacuate Collection Set: 0.0ms [0.942s][info][gc,phases ] GC(192) Evacuate Collection Set: 0.4ms [0.942s][info][gc,phases ] GC(192) Post Evacuate Collection Set: 0.0ms [0.942s][info][gc,phases ] GC(192) Other: 0.0ms [0.942s][info][gc,heap ] GC(192) Eden regions: 0->0(1) [0.942s][info][gc,heap ] GC(192) Survivor regions: 0->0(1) [0.942s][info][gc,heap ] GC(192) Old regions: 10->10 [0.942s][info][gc,heap ] GC(192) Humongous regions: 0->0 [0.942s][info][gc,metaspace ] GC(192) Metaspace: 5993K->5993K(1056768K) [0.942s][info][gc ] GC(192) Pause Initial Mark (G1 Evacuation Pause) 9M->9M(10M) 0.530ms [0.942s][info][gc,cpu ] GC(192) User=0.00s Sys=0.00s Real=0.00s [0.942s][info][gc ] GC(193) Concurrent Cycle [0.942s][info][gc,marking ] GC(193) Concurrent Clear Claimed Marks [0.942s][info][gc,marking ] GC(193) Concurrent Clear Claimed Marks 0.004ms [0.942s][info][gc,marking ] GC(193) Concurrent Scan Root Regions [0.942s][info][gc,marking ] GC(193) Concurrent Scan Root Regions 0.003ms [0.942s][info][gc,marking ] GC(193) Concurrent Mark (0.942s) [0.942s][info][gc,marking ] GC(193) Concurrent Mark From Roots [0.942s][info][gc,task ] GC(193) Using 2 workers of 2 for marking [0.942s][info][gc,start ] GC(194) Pause Full (Allocation Failure) [0.943s][info][gc,phases,start] GC(194) Phase 1: Mark live objects [0.946s][info][gc,stringtable ] GC(194) Cleaned string and symbol table, strings: 3222 processed, 0 removed, symbols: 25923 processed, 0 removed [0.946s][info][gc,phases ] GC(194) Phase 1: Mark live objects 3.168ms [0.946s][info][gc,phases,start] GC(194) Phase 2: Compute new object addresses [0.946s][info][gc,phases ] GC(194) Phase 2: Compute new object addresses 0.418ms [0.946s][info][gc,phases,start] GC(194) Phase 3: Adjust pointers [0.949s][info][gc,phases ] GC(194) Phase 3: Adjust pointers 2.706ms [0.949s][info][gc,phases,start] GC(194) Phase 4: Move objects [0.949s][info][gc,phases ] GC(194) Phase 4: Move objects 0.005ms [0.949s][info][gc,task ] GC(194) Using 8 workers of 8 to rebuild remembered set [0.951s][info][gc,heap ] GC(194) Eden regions: 0->0(1) [0.951s][info][gc,heap ] GC(194) Survivor regions: 0->0(1) [0.951s][info][gc,heap ] GC(194) Old regions: 10->10 [0.951s][info][gc,heap ] GC(194) Humongous regions: 0->0 [0.951s][info][gc,metaspace ] GC(194) Metaspace: 5993K->5993K(1056768K) [0.951s][info][gc ] GC(194) Pause Full (Allocation Failure) 9M->9M(10M) 8.955ms [0.951s][info][gc,cpu ] GC(194) User=0.01s Sys=0.00s Real=0.01s
G1收集器博大精深,有待進一步實踐進行深刻理解研究。oop