本文來自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
在G1中,爲了提高吞吐量,有一些操做永遠是(STW) stop-the-world 的。其餘的一些要長期的,如全局標記這種要全堆進行的操做與應用程序併發進行。爲了讓空間回收的 STW 儘量減小,G1並行的分步的遞增進行空間回收。G1經過追蹤此前應用行爲和垃圾回收停頓的信息來構建一個與開銷有關的模型(Pause Prediction Model)。它使用這些信息停頓期間可作的工做。舉個例子,G1首先回收最高效的區域(也即垃圾最滿的區域,所以稱爲垃圾—優先)。數據結構
G1把堆分紅了n個大小相同的region 併發
自從 Java9 後,引入的統一的日誌,也就是 Xlog 參數。下面是建議的 GCLog 參數:oracle
-Xlog:gc*:file=your.log:tags,time,uptime,level:filecount=5,filesize=100
咱們明白,調優的基本步驟就是jvm
只有明白了GC內部發生了什麼,才能針對性的對其進行調整。spa
下面經過一些正常的 GC log 來理解 GC 的三種方式 GC 作了什麼。3d
先用張圖來簡單理解 Young GC 過程
-XX:G1NewSizePercent
(默認:5) Young region 最小值-XX:G1MaxNewSizePercent
(默認: 60) Young region 最大值
-XX:G1MaxNewSizePercent
與 Young 關聯-XX:MixedGCCountTarget
與 old 關聯-XX:MixedGCCountTarget
默認是8,意味着要在8次之內回收完全部的 old region-XX:G1MixedGCLiveThresholdPercent
(默認:85)可能會提升堆使用率-XX:G1HeapWastePercent
(默認:5) 若是可回收低於這個值, 那麼將不會啓動Mixed gc
G1 有兩個階段,它會在這兩個階段往返,分別是 Young-only,Space Reclamation.
圖是來自 oracle 上對 gc 週期的描述,實心圓都表示一次 GC 停頓
在幾回gc後,old gen 的對象佔有比超過了 InitiatingHeapOccupancyPercent
,gc就會進入併發標記準備(concurrent mark)。
回到 full gc,從上面簡單分析得出,full gc 發生是沒有足夠的 free region,若是堆是足夠大的,Mixed gc 沒有回收足夠的 old region,或者 concurrent mark 無法及時完成,均可能會致使 full gc。
[gc,start ] GC(78) Pause Young (Normal) (G1 Evacuation Pause)
上面是連續幾回GC的日誌,能夠對照着 gc 週期來看。爲了方便排版,把時間相關的tag給精簡掉了。
根據日誌,能夠簡單看到每一個步驟花費的時間,以及對應區域垃圾的回收狀況,結合GC參數,能夠定位出什麼問題,針對性的調整參數。
吞吐量跟低延時是沒法兼得的,低延時意味着GC工做會更加頻繁,相對的,會佔用應用的資源,吞吐量下降。須要大吞吐量,那麼GC工做就會減小,相對的,每次回收的垃圾就會多,暫停時間就會增長,延時就會增長。
-XX:MaxGCPauseMillis
G1 會盡可能知足這個參數設定的目標時間,經過此參數能夠平衡應用須要的吞吐量以及延時。
本文主要參考資料是官方的文章和文檔,沒涉及到複雜的內部實現,新版的JDK除了對G1進行了改良以外,還推出了幾種新的。
因爲知識簡陋,不免會有勘誤,歡迎討論。
1.https://docs.oracle.com/en/ja...
2.https://chriswhocodes.com/hot..._options_jdk11.html
3.https://www.oracle.com/techne...