記一次頻繁FGC的簡單排查

簡書 占小狼
轉(zhuǎn)載請注明原創(chuàng)出處,謝謝!
如果讀完覺得有收獲的話,歡迎點(diǎn)贊加關(guān)注

周末愉快,今天有時間記錄一下上周遇到的一個問題,學(xué)習(xí)的腳步不能放慢,也不敢放慢。

存在問題

在線上環(huán)境進(jìn)行服務(wù)壓測,壓測完成后,cpu使用率居高不下,很是費(fèi)解,按理說已經(jīng)沒有壓測請求了,這時消耗cpu資源的只有GC線程了,可以通過jstat命令查看一下JVM的GC情況,然后就碰到了詭異的GC問題。

jstat命令

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]

參數(shù):
generalOption: 一般使用-gcutil查看GC情況
vmid: 虛擬機(jī)進(jìn)程號,即當(dāng)前運(yùn)行的java進(jìn)程號
interval: 間隔時間,單位為秒或毫秒
count: 打印次數(shù),如果缺省則打印無數(shù)次

執(zhí)行jstat -gcutil 9132 1000命令,線上服務(wù)器的GC情況如下:

參數(shù)說明如下:
S0: 新生代中Survivor space 0區(qū)已使用空間的百分比
S1: 新生代中Survivor space 1區(qū)已使用空間的百分比
E: 新生代已使用空間的百分比
O: 老年代已使用空間的百分比
P: 永久帶已使用空間的百分比
YGC: 從應(yīng)用程序啟動到當(dāng)前,發(fā)生Yang GC 的次數(shù)
YGCT: 從應(yīng)用程序啟動到當(dāng)前,Yang GC所用的時間【單位秒】
FGC: 從應(yīng)用程序啟動到當(dāng)前,發(fā)生Full GC的次數(shù)
FGCT: 從應(yīng)用程序啟動到當(dāng)前,F(xiàn)ull GC所用的時間
GCT: 從應(yīng)用程序啟動到當(dāng)前,用于垃圾回收的總時間【單位秒】

問題分析

通過打印的GC數(shù)據(jù)可以看出,JVM一直在進(jìn)行FGC(cms gc),不過老年代的使用率反而沒有下降,一直穩(wěn)定在60.16%,對這一情況很疑惑,幾乎每次都重現(xiàn),后來去仔細(xì)查看了JVM的啟動參數(shù),發(fā)現(xiàn)其中CMSInitiatingOcupancyFraction參數(shù),被設(shè)置成60,意味著當(dāng)老年代的使用率達(dá)到閾值60%時會觸發(fā)FGC,但是FGC之后,老年代的使用率還是大于60%,所以會不斷的進(jìn)行FGC,建議這個值不要設(shè)置的這么小。

至于為什么FGC之后,老年代的使用率沒有下降,可以通過dump查看到底是哪些存活對象在作怪,在進(jìn)行FGC時,通常會伴隨著一次YGC,但這也不是一定的,如果執(zhí)行YGC之后沒有明顯效果的話,會設(shè)置一個變量,表明下次不用進(jìn)行YGC,所以如果老年代如果存在大量對象的GC ROOT在新生代的話,這些對象就不會被回收,這種情況必須強(qiáng)制執(zhí)行一次YGC之后,才有可能回收這些老年代的對象,比如添加參數(shù)-XX:+CMSScavengeBeforeRemark,就可以解這個問題。

昨天正好笨神也遇到類似的問題,并寫一篇文章《又抓了一個導(dǎo)致頻繁GC的鬼--數(shù)組動態(tài)擴(kuò)容》進(jìn)行分析,可以參考一下。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容