jvm gc查看
jstat -gcutil pid interval(ms)
舉例:
jstat -gcutil 332 1000
執行jstat -gcutil 9132 1000
命令,線上服務器的GC情況如下:
參數說明如下:
S0: 新生代中Survivor space 0區已使用空間的百分比
S1: 新生代中Survivor space 1區已使用空間的百分比
E: 新生代已使用空間的百分比
O: 老年代已使用空間的百分比
P: 永久帶已使用空間的百分比
YGC: 從應用程序啓動到當前,發生Yang GC 的次數
YGCT: 從應用程序啓動到當前,Yang GC所用的時間【單位秒】
FGC: 從應用程序啓動到當前,發生Full GC的次數
FGCT: 從應用程序啓動到當前,Full GC所用的時間
GCT: 從應用程序啓動到當前,用於垃圾回收的總時間【單位秒】
問題分析
通過打印的GC數據可以看出,JVM一直在進行FGC(cms gc),不過老年代的使用率反而沒有下降,一直穩定在60.16%,對這一情況很疑惑,幾乎每次都重現,後來去仔細查看了JVM的啓動參數,發現其中CMSInitiatingOcupancyFraction
參數,被設置成60,意味着當老年代的使用率達到閾值60%時會觸發FGC,但是FGC之後,老年代的使用率還是大於60%,所以會不斷的進行FGC,建議這個值不要設置的這麼小。
至於爲什麼FGC之後,老年代的使用率沒有下降,可以通過dump查看到底是哪些存活對象在作怪,在進行FGC時,通常會伴隨着一次YGC,但這也不是一定的,如果執行YGC之後沒有明顯效果的話,會設置一個變量,表明下次不用進行YGC,所以如果老年代如果存在大量對象的GC ROOT在新生代的話,這些對象就不會被回收,這種情況必須強制執行一次YGC之後,纔有可能回收這些老年代的對象,比如添加參數-XX:+CMSScavengeBeforeRemark
,就可以解這個問題。