一分鐘瞭解G1收集器,它就是這麼簡單

1.G1收集器收集器定義

G1 (Garbage-First)是一款面向伺服器的垃圾收集器,

主要針對配備多顆處理器及大容量記憶體的機 器

。 以極高機率滿足GC停頓時間要求的同時,還具備高吞吐量效能特徵。

記住G1是適合大記憶體機器的!

2.G1收集器的結構:

一分鐘瞭解G1收集器,它就是這麼簡單

G1將Java堆劃分為多個大小相等的獨立區域(Region),JVM最多可以有2048個Region。

Region可分為:

Eden: 新生代區域

Survivor:交換區域

Old:老年代區域

Humongous:大物件區域,用於存放大小大於Region一半以上的物件。

特點:

1。

一般Region大小等於堆大小除以2048

,比如堆大小為4096M,則Region大小為2M,當然也可以用引數“-XX:G1HeapRegionSize”手動指定Region大小,但是推薦預設的計算方式。

2。

G1保留了年輕代和老年代的概念,但不再是物理隔閡了,它們都是(可以不連續)Region的集合。

3.預設年輕代對堆記憶體的佔比是5%。

可以透過“-XX:G1NewSizePercent”設定新生代初始佔比。

4.新生代的佔比最多不會超過60%

,可以透過“-XX:G1MaxNewSizePercent”調整。

5。

年輕代中的Eden和Survivor對應的region也跟之前 一樣,

預設8:1:1。

6。

G1有專門分配大物件的Region叫Humongous區

7。在G1中,大物件的判定規則就是一個大物件超過了一個Region大小的50%。

8。

Humongous區專門存放短期巨型物件,不用直接進老年代,可以節約老年代的空間,避免因為老年代空間不夠的GC開銷。

9。Full GC的時候除了收集年輕代和老年代之外,也會將Humongous區一併回收。

3.G1垃圾收集GC

YoungGC

YoungGC並不是說現有的Eden區放滿了就會馬上觸發,而且G1會計算下現在Eden區回收大概要多久時間,如果回收時間遠遠小於引數( -XX:MaxGCPauseMills)設定的值,那麼增加年輕代 的region,繼續給新物件存放,不會馬上做Young GC,直到下一次Eden區放滿,G1計算回收時 間接近引數( -XX:MaxGCPauseMills)設定的值,那麼就會觸發Young GC

MixedGC

不是FullGC,老年代的堆佔有率達到引數(-XX:InitiatingHeapOccupancyPercen)設定的值則觸發,回收所有的Young和部分Old(根據期望的GC停頓時間確定old區垃圾收集的優先順序)以及大物件區,正常情況G1的垃圾收集是先做MixedGC,主要

使用複製演算法

,需要把各個region中存活的物件複製到別的region裡去,複製過程中如果發現沒有足夠的空region能夠承載複製物件 就會觸發一次FullGC 。

Full GC

停止系統程式,然後採用單執行緒進行標記、清理和壓縮整理,好空閒出來一批Region來供下 一次MixedGC使用,這個過程是非常耗時的。

4.G1收集器一次GC的運作過程大致分為以下幾個步驟:

初始標記(initial mark,STW)

:暫停所有的其他執行緒,並記錄下gc roots直接能引用 的物件,速度很快 ;

併發標記(Concurrent Marking):

同CMS的併發標記

最終標記(Remark,STW):

同CMS的重新標記

篩選回收(Cleanup,STW):

篩選回收階段首先對各個Region的回收價值和成本進行 排序,根據使用者所期望的GC停頓時間(可以用JVM引數 -XX:MaxGCPauseMillis指定)來自 定回收計劃。

回收演算法主要用的是複製演算法

一分鐘瞭解G1收集器,它就是這麼簡單

G1收集器執行過程

5.G1收集器引數設定

-XX:+UseG1GC:

使用G1收集器

-XX:ParallelGCThreads:指定GC工作的執行緒數量

-XX:G1HeapRegionSize:指定分割槽大小(1MB~32MB,且必須是2的冪),預設將整堆劃分為 2048個分割槽

-XX:MaxGCPauseMillis:目標暫停時間(預設200ms)

-XX:G1NewSizePercent:新生代記憶體初始空間(預設整堆5%)

-XX:G1MaxNewSizePercent:新生代記憶體最大空間

-XX:TargetSurvivorRatio:

Survivor區的填充容量(預設50%),Survivor區域裡的一批物件(年齡 1+年齡2+年齡n的多個年齡物件)總和超過了Survivor區域的50%,此時就會把年齡n(含)以上的對 象都放入老年代

-XX:MaxTenuringThreshold:最大年齡閾值(預設15)

-XX:InitiatingHeapOccupancyPercent:

老年代佔用空間達到整堆記憶體閾值(預設45%),則執行 新生代和老年代的混合收集(MixedGC),比如我們之前說的堆預設有2048個region,如果有接近 1000個region都是老年代的region,則可能就要觸發MixedGC了

-XX:G1HeapWastePercent(預設5%): gc過程中空出來的region是否充足閾值,在混合回收的時候,對Region回收都是基於複製演算法進行的,都是把要回收的Region裡的存活物件放入其他 Region,然後這個Region中的垃圾物件全部清理掉,這樣的話在回收過程就會不斷空出來新的 Region,一旦空閒出來的Region數量達到了堆記憶體的5%,此時就會立即停止混合回收,意味著 本次混合回收就結束了。

-XX:G1MixedGCLiveThresholdPercent(預設85%)

region中的存活物件低於這個值時才會回收 該region,如果超過這個值,存活物件過多,回收的的意義不大。

-XX:G1MixedGCCountTarget:在一次回收過程中指定做幾次篩選回收(預設8次),在最後一個篩 選回收階段可以回收一會,然後暫停回收,恢復系統執行,一會再開始回收,這樣可以讓系統不至 於單次停頓時間過長。