深入理解JVM 一GC(下) G1 Garbage Collector

深入理解JVM 一GC(下) G1 Garbage Collector

關於java程式效能

當我們調優java程式時,通常的目標有兩個:
響應能力 或者 吞吐量

響應能力

響應能力指一個程式或者系統對請求的是否能夠及時響應。
比如:
一個桌面UI能多快的響應一個事件;
一個網站能夠多快返回一個頁面請求;
資料庫能夠多快返回查詢的資料;

對於這類對響應能力敏感的場景,長時間的停頓是無法接受的。

吞吐量

吞吐量關注的是,在一個指定的時間內,最大化一個應用的工作量。
如下方式來衡量一個系統吞吐量的好壞:

在一小時內同一個事務(或者任務、請求)完成的次數(tps)。
資料庫一小時可以完成多少次查詢;

對於關注吞吐量的系統,卡頓是可以接受的,因為這個系統關注長時間的大量任務的執行能力,單次快速的響應並不值得考慮。

應用程式執行實際/實際時間(開始時間戳-結束時間戳)

understanding TPS

G1 Garbage Collector

G1垃圾收集器

g1收集器是一個面向服務端的垃圾收收集器,適用於多核處理器、大記憶體容量的服務端系統。
它滿足短時間gc 停頓的同時達到一個高的吞吐量。JDK7以上版本適用。

g1收集器的設計目標:

與應用執行緒同時工作,幾乎不需要stop-the-world(與CMS類似);
整理剩餘空間,不產生記憶體碎片;(CMS只能在full-GC時,用stop-the-world整理碎片記憶體)
GC停頓更加可控;
不犧牲系統的吞吐量;
gc不要求額外的記憶體空間(CMS需要預留空間儲存浮動垃圾);

G1的設計規劃,是要替換掉CMS。

G1在某些方便彌補了CMS的不足,比如,CMS使用的是mark-sweep演算法,自然會產生記憶體碎片;然而G1基於copying演算法,高效的整理剩餘記憶體,而不需要使用free-list去管理記憶體碎片。
另外,G1提供了更多手段,以達到對gc停頓時間可控。

之前的GC收集器對Heap的劃分:

這裡寫圖片描述

G1對Heap的劃分:

這裡寫圖片描述

heap被劃分為一個個相等的不連續的記憶體區域(regions),每個region都有一個分代的角色:eden、survivor、old(old還有一種細分 humongous,用來存放大小超過 region 50%以上的巨型物件)。

但是對每個角色的數量並沒有強制的限定,也就是說對每種分代記憶體的大小,可以動態變化(預設年輕代佔整個heap的5%)。

G1最大的特點就是高效的執行回收,優先去執行那些大量物件可回收的區域(region)。

另外,G1使用了gc停頓可預測的模型,來滿足使用者設定的gc停頓時間,根據使用者設定的目標時間,g1會自動的選擇哪些region要清楚,一次清除多少個region。

G1從多個region中複製存活的物件,然後集中放入一個region中,同時整理、清除記憶體(copying收集演算法)。

注意對比之前的垃圾收集器(主要是CMS):
對比使用mark-sweep的CMS,g1使用的copying演算法不會造成記憶體碎片
對比ParallelScavenge(基於copying )、ParallelOld收集器(基於mark-compact-sweep),Parallel
會對整個區域做整理導致gc Pause會比較長,而g1只是特定的整理幾個region。

值得注意:g1不是一個實時的收集器,與parallelScavenge一樣,對gc 停頓時間的設定並不絕對生效,只是g1有較高的機率保證不超過設定gc停頓時間。與之前的gc收集器對比,g1會根據使用者設定的gc停頓時間,智慧評估一下哪幾個region需要被回收可以滿足使用者設定。

G1記憶體的分配

1.TLAB(TLAB佔用年輕代記憶體). 預設使用TLAB加速記憶體分配,之前文章已經講過,不贅述。
2.Eden.如果TLAB不夠用,則在Eden中分配記憶體生成物件。
3.Humongous.如果物件需要的記憶體超過一個region的50%以上,會忽略前兩個步驟直接在老年代的humongous中分配(連續的Region)。

何時使用G1(-XX: UseG1GC)

1.大記憶體中為了達到低gc延遲.
比如:heap size >=6G,gc pause <=0.5s
2.FullGC時間太長,或者太頻繁。

調優引數:
-XX:MaxGCPauseMillis=200
使用者設定的最大gc 停頓時間,預設是200ms.
-XX:InitiatingHeapOccupancyPercent=45
預設是45,也就是heap中45%的容量被使用,則會觸發concurrent gc。

G1垃圾回收步驟詳解

G1提供了兩種GC模式,Young GC和Mixed GC,兩種都是Stop The World(STW)的

G1 Young GC(STW)

1.當eden資料滿了,則觸發g1 YGC
2.並行的執行:
YGC 將 eden region 中存活的物件拷貝到survivor,或者直接晉升到Old Region中;將Survivor Regin中存活的物件拷貝到新的Survivor或者晉升old region。
3.計算下一次YGC eden、Survivor的尺寸

G1 Mix GC

在G1 GC中,它主要是為Mixed GC提供標記服務的,並不是一次GC過程的一個必須環節。global concurrent marking的執行過程分為五個步驟:

初始標記(initial mark,STW)
在此階段,G1 GC 對根進行標記。該階段與常規的 (STW) 年輕代垃圾回收密切相關。

根區域掃描(root region scan)
G1 GC 在初始標記的存活區掃描對老年代的引用,並標記被引用的物件。該階段與應用程式(非 STW)同時執行,並且只有完成該階段後,才能開始下一次 STW 年輕代垃圾回收。

併發標記(Concurrent Marking)
G1 GC 在整個堆中查詢可訪問的(存活的)物件。該階段與應用程式同時執行,可以被 STW 年輕代垃圾回收中斷

最終標記(Remark,STW)
該階段是 STW 回收,幫助完成標記週期。G1 GC 清空 SATB 緩衝區,跟蹤未被訪問的存活物件,並執行引用處理。

清除垃圾(Cleanup,STW)
在這個最後階段,G1 GC 執行統計和 RSet 淨化的 STW 操作。在統計期間,G1 GC 會識別完全空閒的區域和可供進行混合垃圾回收的區域。清理階段在將空白區域重置並返回到空閒列表時為部分併發。

g1 對老年代回收-總結:

1.併發標記階段(Concurrent Marking Phase):
在不產生stop-the-world,與程式程序併發的情況下,活躍度(可達性分析)被分析出來。
活躍度越低,代表回收的效率越高,越值得優先回收。
2.複製、清理階段(Copying/Cleanup Phase)
年輕代、老年代在這個階段同時被回收掉。老年代被回收的region,是根據這個region的存活度來選擇的。

更多詳細資訊請點選