G1GC 概念與性能調優

本文來自OPPO互聯網技術團隊,轉載請註名做者。同時歡迎關注咱們的公衆號:OPPO_tech,與你分享OPPO前沿互聯網技術及活動。html

本文不討論 G1 底層數據結構與算法,從 G1 GC 行爲上作簡要介紹 G1 的過程

Garbage-First Garbage Collector 從官網的描述來看:java

G1 is a generational, incremental, parallel, mostly concurrent, stop-the-world, and evacuating garbage collector which monitors pause-time goals in each of the stop-the-world pauses. Similar to other collectors, G1 splits the heap into (virtual) young and old generations. Space-reclamation efforts concentrate on the young generation where it is most efficient to do so, with occasional space-reclamation in the old generation.算法

從介紹能夠加粗幾個重點segmentfault

  • 分代
  • 併發
  • STW
  • 在每一個STW階段關注暫停時間目標
  • 回收主要集中在最有效的young generation, old generation則沒這麼頻繁

在G1中,爲了提高吞吐量,有一些操做永遠是(STW) stop-the-world 的。其餘的一些要長期的,如全局標記這種要全堆進行的操做與應用程序併發進行。爲了讓空間回收的 STW 儘量減小,G1並行的分步的遞增進行空間回收。G1經過追蹤此前應用行爲和垃圾回收停頓的信息來構建一個與開銷有關的模型(Pause Prediction Model)。它使用這些信息停頓期間可作的工做。舉個例子,G1首先回收最高效的區域(也即垃圾最滿的區域,所以稱爲垃圾—優先)。數據結構

G1把堆分紅了n個大小相同的region 併發

  • E 是 eden region
  • S 是 survivor region
  • O 是 old region
  • H 是 humongous (老年代能夠是 humongous,能夠看出,他能夠跨越多個連續regions。直接分配到老年代,防止反覆拷貝移動)

Java 9 之後開啓的參數

自從 Java9 後,引入的統一的日誌,也就是 Xlog 參數。下面是建議的 GCLog 參數:oracle

-Xlog:gc*:file=your.log:tags,time,uptime,level:filecount=5,filesize=100

G1 的 GC 階段

咱們明白,調優的基本步驟就是jvm

  1. Measure 收集相關診斷信息 (例如收集詳細的gclog,默認log level info 能夠知足大部分狀況)
  2. Understand 理解發生了什麼
  3. Tune 調優

只有明白了GC內部發生了什麼,才能針對性的對其進行調整。spa

下面經過一些正常的 GC log 來理解 GC 的三種方式 GC 作了什麼。3d

Young Only Phase

先用張圖來簡單理解 Young GC 過程

  • 垃圾回收的過程就是 Allocated->eden; eden -> survivor; survivor -> survivor; survivor -> old;

  • 能夠看到,這裏有 eden,survivor,old 還有個 free region。

  • 橙色就是活着的對象

  • G1會把橙色對象拷貝到free region

  • 當拷貝完畢,free region 就會晉升爲 survivor region,之前的 eden 就被釋放了
  • 若是 Young gc 中,花費了大量的時間
  • 正常來講,大部分在 Young 的對象都不會存活很長時間
  • 若是不符合這個規則 (大部分在 Young 的對象都不會存活很長時間),你可能須要調整一下 Young 區域佔比。來下降 Young 對象的拷貝時間。
  • -XX:G1NewSizePercent (默認:5) Young region 最小值
  • -XX:G1MaxNewSizePercent (默認: 60) Young region 最大值

Mixed gc Phase

  • Mixed gc 會選取全部的 Young region + 收益高的若干個 Old region。

  • 一樣的,被回收的 region 就變回 free region 了
  • 從上圖能夠了解到 Mixed gc 只能回收部分的老年代
  • G1 是如何選擇要回收的 regions 的?
  • -XX:G1MaxNewSizePercent 與 Young 關聯
  • -XX:MixedGCCountTarget 與 old 關聯
  • -XX:MixedGCCountTarget默認是8,意味着要在8次之內回收完全部的 old region
  • 換句話說,若是你有 800 個 old region, 那麼一次 mixed gc 最大會回收 100 個 old region
  • G1 也能夠被調整成不作這麼多工做,也就是回收少點,浪費堆內存,致使更堆使用
  • -XX:G1MixedGCLiveThresholdPercent(默認:85)可能會提升堆使用率
  • -XX:G1HeapWastePercent (默認:5) 若是可回收低於這個值, 那麼將不會啓動Mixed gc

Full gc Phase

  • Full gc 是不該該發生的

先來看看 GC 週期

G1 有兩個階段,它會在這兩個階段往返,分別是 Young-only,Space Reclamation.

  • Young-only 包含一系列逐漸填滿 old gen 的 gc
  • Space Reclamation G1 會遞進地回收 old gen 的空間,同時也處理 Young region

圖是來自 oracle 上對 gc 週期的描述,實心圓都表示一次 GC 停頓

  • 藍色 Young-only
  • 黃色 標記過程的停頓
  • 紅色 Mixed gc 停頓

在幾回gc後,old gen 的對象佔有比超過了 InitiatingHeapOccupancyPercent,gc就會進入併發標記準備(concurrent mark)。

  • G1 在每一次 Young 回收中都會查找活對象(有引用的對象)
  • G1 在 old region 併發查找活對象
  • 叫 concurrent marking
  • 可能花費很長時間
  • 不會中止 Java 應用
  • G1 沒有活對象的引用信息是不能進行垃圾回收的
  • Mixed gc 依賴 concurrent mark

回到 full gc,從上面簡單分析得出,full gc 發生是沒有足夠的 free region,若是堆是足夠大的,Mixed gc 沒有回收足夠的 old region,或者 concurrent mark 無法及時完成,均可能會致使 full gc。

gc 日誌

[gc,start     ] GC(78) Pause Young (Normal) (G1 Evacuation Pause)

上面是連續幾回GC的日誌,能夠對照着 gc 週期來看。爲了方便排版,把時間相關的tag給精簡掉了。

  • GC(78) 是一次普通的young gc,裏面信息有各類 region 的變化
  • 這裏簡單說一下 humongous 對象的處理
  • humongous 對象在G1中是被特殊對待的,G1 只決定它們是否生存,回收他們佔用的空間,從不會移動它們
  • Young-Only 階段,humongous regions 可能會被回收
  • Space-Reclamation,humongous regions 可能會被回收
  • GC(79) 開始進入併發階段
  • GC(80) 完成了 Cleanup,緊接着一個 Prepare Mixed GC(81) 的垃圾收集,對應週期虛線右邊的藍實心圓
  • GC(82) 以後就是 Space Reclamation 階段了,多個 Mixed GC 會進行

根據日誌,能夠簡單看到每一個步驟花費的時間,以及對應區域垃圾的回收狀況,結合GC參數,能夠定位出什麼問題,針對性的調整參數。

吞吐量跟低延時是沒法兼得的,低延時意味着GC工做會更加頻繁,相對的,會佔用應用的資源,吞吐量下降。須要大吞吐量,那麼GC工做就會減小,相對的,每次回收的垃圾就會多,暫停時間就會增長,延時就會增長。 -XX:MaxGCPauseMillis G1 會盡可能知足這個參數設定的目標時間,經過此參數能夠平衡應用須要的吞吐量以及延時。

最後

本文主要參考資料是官方的文章和文檔,沒涉及到複雜的內部實現,新版的JDK除了對G1進行了改良以外,還推出了幾種新的。

  1. Epsilon GC (no-op),無操做垃圾回收器,簡單點就是不回收垃圾,等堆空間分配完了,jvm也就中止了
  2. zgc 超大堆垃圾回收器,暫停不超過10ms,支持T級別的堆
  3. Shenandoah 一樣也是低延遲垃圾回收器

因爲知識簡陋,不免會有勘誤,歡迎討論。

參考資料

1.https://docs.oracle.com/en/ja...

2.https://chriswhocodes.com/hot..._options_jdk11.html

3.https://www.oracle.com/techne...

相關文章
相關標籤/搜索