深入理解Java虛擬機器筆記之五GC日誌和垃圾收集器引數

zhumeilu發表於2019-01-18

GC日誌

[GC (Allocation Failure) [PSYoungGen: 5632K->496K(6144K)] 5632K->2985K(19968K), 0.0061449 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 6128K->512K(6144K)] 8617K->7656K(19968K), 0.0066923 secs] [Times: user=0.04 sys=0.01, real=0.00 secs] 
[Full GC (Ergonomics) [PSYoungGen: 6144K->0K(6144K)] [ParOldGen: 10309K->12187K(13824K)] 16453K->12187K(19968K), [Metaspace: 3288K->3288K(1056768K)], 0.1817402 secs] [Times: user=0.33 sys=0.01, real=0.18 secs] 
[Full GC (Ergonomics) [PSYoungGen: 4227K->2629K(6144K)] [ParOldGen: 12187K->13610K(13824K)] 16414K->16239K(19968K), [Metaspace: 3288K->3288K(1056768K)], 0.1551767 secs] [Times: user=0.39 sys=0.01, real=0.16 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 2629K->2629K(6144K)] [ParOldGen: 13610K->13592K(13824K)] 16239K->16222K(19968K), [Metaspace: 3288K->3288K(1056768K)], 0.0977081 secs] [Times: user=0.43 sys=0.01, real=0.10 secs] 

複製程式碼

GC日誌開頭的“[GC”和“[Full GC”說明了這次垃圾收集的停頓型別,而不是用來區分新生代GC還是老年代GC的。如果有“full”,說明這次GC是發生了Stop The World的,例如下面這段新生代收集器ParNew的日誌也會出現“Full GC”,這一般是因為出現了分配擔保失敗之類的問題,所以才導致STW。如果是呼叫System.gc()方法所觸發的收集,那麼在這裡將顯示“[Full GC(System)”。

[Full GC 283.736:[ParNew:261599K->261599K(261952K),0.0000288 secs]

接下來“[DefNew”、“[Tenured”、“[Perm”、“[PSYoungGen”表示GC發生的區域,這裡顯示的區域名稱與使用的GC收集器是密切相關的,例如Serial收集器為“[DefNew”,ParNew收集器為“[ParNew”,如果是Parallel Scavenge收集器,那它配套的新生代為“PSYoungGen”,老年代和永久代同理,名稱也是由收集器決定的。

後面方括號內部的“5632K->496K(6144K)” 含義是“GC前該記憶體區域已使用容量->GC後該記憶體區域已使用容量(該記憶體區域總容量)”。

而在方括號之外的“5632K->2985K(19968K)”表示“GC前Java堆已使用容量->GC後Java堆已使用容量(Java堆總容量)”

再往後,“0.0061449 secs”表示該記憶體區域GC所佔用的時間,單位是秒。“[Times: user=0.02 sys=0.00, real=0.00 secs] ”,這裡面的user、sys、和real與linux的time命令所輸出的時間含義一致,分別代表使用者態消耗的CPU時間、核心態消耗的CPU時間和操作從開始到結束所經歷過的牆鍾時間。CPU時間與牆鍾時間的區別是,牆鍾時間包括各種非運算的等待耗時,例如等待磁碟IO,等待執行緒阻塞,而CPU時間不包括這些耗時,但當系統有多CPU或者多核的話,多執行緒操作會疊加這些CPU時間,所以user或者sys時間超過real時間是完全正常的。

垃圾收集器引數總結

引數 描述
UseSerial 虛擬機器執行在Client模式下的預設值,開啟此開關後,使用Serial+Serial Old 的收集器組合進行記憶體回收
UseParNewGC 開啟此開關後,使用ParNew+Serial Old的收集器組合進行記憶體回收
UseConcMarkSweepGC 開啟此開關後,使用ParNew+CMS+Serial Old的收集器組合進行記憶體回收。Serial Old收集器將作為CMS收集器出現Concurrent Mode Failure失敗後的後備收集器使用
UseParallelGC 虛擬機器執行在Server模式下的預設值,開啟此開關後,使用Parallel Scavenge+Serial Old(Ps Mark Sweep)的收集器組合進行記憶體回收
UseParllelOldGC 開啟此開關後,使用Parallel Scavenge+Parallel Old 的收集器組合進行記憶體回收
SurvivorRatio 新生代中Eden區域與Survivor區域的容量比值,預設為8,代表Eden:Survivor = 8:1
PretenureSizeThreshold 直接晉升到老年代的物件大小,設定這個引數後,大於這個引數的物件將直接在老年代分配
MaxTenuringThreshold 晉升到老年代的物件年齡。每個物件在堅持過一次Minor GC之後,年齡就+1,當超過這個引數值時就進入老年代
UseAdaptiveSizePolicy 動態調整Java堆中各個區域的大小以及進入老年代的年齡
HandlePromotionFailure 是否允許分配擔保失敗,即老年代的剩餘空間不足以應付新生代的整個Eden和Survivor區的所有物件都存活的極端情況
ParallelGCThreads 設定並行GC時進行記憶體回收的執行緒數
GCTimeRatio GC時間佔總時間的比率,預設為99,即允許1%的GC時間。僅在使用Parallel Scavenge收集器時生效
MaxGCPauseMillis 設定GC的最大停頓時間。僅在使用Parallel Scavenge收集器時生效
CMSInitiatingOccupancyFraction 設定CMS收集器在老年代空間被使用多少後觸發垃圾收集。預設值為68%。僅在使用CMS收集器時生效
UseCmsCompactAtFullCollection 設定CMS收集器在完成垃圾收集後是否要進行一次記憶體碎片整理。僅在使用CMS收集器時生效
CMSFullGCsBeforeCompaction 設定CMS收集器在進行若干次垃圾收集後再啟動一次記憶體碎片整理。僅在使用CMS收集器時生效

相關文章