java9系列(九)Make G1 the Default Garbage Collector

本文主要研究下JEP 248: Make G1 the Default Garbage Collectorhtml

默認垃圾收集器

java9廢棄了CMS垃圾收集器,並把G1提高爲默認垃圾收集器,替代了原來的吞吐優先的ParallelOldGC

Region

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

Humongous Object/ Humongous區域

  • 對於G1 GC,任何超過區域一半大小的對象都被視爲「巨型對象」。
  • 此類對象直接被分配到老年代中的「巨型區域」。
  • 這些巨型區域是一個連續的區域集。StartsHumongous 標記該連續集的開始,ContinuesHumongous 標記它的延續。
巨型對象默認直接會被分配在年老代,可是若是它是一個短時間存在的巨型對象,就會對垃圾收集器形成負面影響。爲了解決這個問題,G1劃分了一個Humongous區,它用來專門存放巨型對象。若是一個H區裝不下一個巨型對象,那麼G1會尋找連續的H分區來存儲。爲了能找到連續的H區,有時候不得不啓動Full GC。

GC事件及觸發

GC event

  • Minor GC event
正常的young gc
  • Mixed GC event
Minor GC + (# reclaimable Tenured regions / -XX:G1MixedGCCountTarget) regions of Tenured
  • Full GC event
All regions evacuated,一般Humongous object太多會耗盡空間,致使Full GC
  • Minor/Mixed + To-space exhaustion
Minor/Mixed + rollback + Full GC

觸發時機

  • Eden滿/空間不夠
  • 剩餘空間不夠容納一個Humongous object
  • Humongous object分配成功,同時符合一些GC條件
  • 外部命令觸發(jcmd, jmap, Runtime.gc())

G1 GC分類

主要分爲:Minor GC,Mixed/Old GCgithub

Minor GC/Young GC(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 處理引用隊列 軟引用,弱引用,虛引用處理

Mixed/Old GC(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)目標。

GC日誌實例

簡版使用-Xlog:gc=info,詳細版使用-Xlog:gc*=infoless

ygc

  • 簡版
[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

old gc

  • 簡版
[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

doc

相關文章
相關標籤/搜索