JVM FullGC問題剖析全過程(原創)

 

1. 背景

偶然發現查看線上日誌-Xloggc:******/gc.log下面的日誌,發現線上機器存在Full GC,查找其他服務發現都會有這個問題,

基於我們系統很多垃圾回收機制都是ParalllelGC,即吞吐量優先GC方式,GC線上在處理任務時會造成系統stop the wrold暫停,而且GC

時間相對CMS等收集器而已要更長,雖然這些Full GC暫時無明顯停頓,但是出於優化原則進行了一輪排查。下面是對幾臺線上機器的比對。

比對發現線上服務最後一次啓動時間與FullGC出現時間相對吻合。

 

 

2. 問題定位

通過觀察比對發現這些Full GC有幾個比較明顯的特點

  1. 每臺機器都有幾個Full GC ,這幾個Full GC的時間間隔並不長
  2. 線上xmx是2g,由新生代佔比3/8的比例看,Full GC產生時PSYongGen ParOldGen並無達到造成Full GC的大小
  3. 將日誌第一次觸發Full GC時間和該服務最後一次啓動時間對比,發現幾乎吻合
  4. Full GC類型屬於Metadata GC Threshold(jdk 1.8纔會打印類型)
     

有次四點,我們可以總結到本次Full GC是由服務時啓動導致的,由於jdk1.8開始jvm用metaspace替代Perm永久區,我們知道永久區是用來存儲已被虛擬機加載的類信息,

常量和靜態變量,然後跑去寒泉子大牛的JVMPocket看到,jdk從1.6到1.8的默認大小都是MetaSpaceSize=21807104字節(20.8M左右),繼續觀察我們會發現這幾次

Full GC前後,Metaspace的使用變化是從20844k→20844k,也就是並沒有發生變化,看起來好像Metaspace並沒有被回收,其實這是JVM的一個BUG,alijdk等自用產品

會將這個問題進行了修復,能看到前後是有變化的,所以如果大家在排查Metaspace的問題時候,希望不要被這個信息騙到

 

3. mat分析內存使用情況

gc前

gc後

我們發現gc前後內存使用情況並無明顯變化,再查看了一下Leak Suspect發現使用內存較多的類是java.lang.ref.Finalizer,此類在finally做流關閉會大量存在,

由於我們用的是dubbo做遠程過程調用,故也屬於正常行爲。

 

4. 大結局

到這裏,我們看到還是MetaSpaceSize設置太小的問題導致,查看參考配置發現很多公司會將MetaSpaceSize設置爲128M,在dev重現了此問題後,設置成

128M,重新看gc日誌並未發現有Full GC問題,到此,我們就成功解決了線上一個Full GC問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章