一次線上服務fullGC原因排查

一、現象
早上九點多又收到了fullGC次數過高的應用監控告警{P1}{故障}JVM Old GC all(#3) full_gc_count  >5}{當前值:28},通過公司使用的監控平臺可以觀察到服務器在這個時間段內確實出現了一些異常情況:

1.負載突然增加

2.fullgc頻率顯著增加,每次時間漸漸增長

3.老年代內存使用率增長很快(大量對象直接進入老年帶),可以看到Survivor區一直被打滿(Survivor功效喪失,大量新生代對象不能及時回收越過Survivor直接進入年老代)




二、工具排查

線上日誌dump

使用jmap -dump:live,format=b,file=xxx [pid]

工具介紹

市面上提供了很多種工具比如visualVM、JMAT、Jprofile和ha等工具,都可以進行內存堆快照文件分析

1、Jprofile

使用Jprofile需要先將文件後綴修改爲hprof,用Jprofile可以一目瞭然的看出是大量對象,而且可以看到具體的方法一級classloader信息


2、ha

使用ha工具需要將dump文件後綴修改爲jvmdump結尾,通過ha.jar工具查看可以看到大對象數量爲66萬多和38萬多,分別佔用了300多兆和65多兆堆內存


3、JMAT

JMAT也是很好用的工具,建議安裝了eclipse的使用

4、visualVM

這裏不建議用visualVM分析,一個需要設置出展示具體的方法或者對象(沒研究出來),而且默認的內存空間比較小,要看大對象需要修改參數
經過試驗後,對於dump文件分析最好是用Jprofile或者ibm出的ha.jar這個工具或者進行分析效果較好
 

三、排查結果分析

1、分析結果驗證

根據工具分析結果,對照着監控中的異常可以看到9點11分時候三次long-SQL中查詢返回了大量對象發現結果和時間都是吻合的,於是進一步排查代碼

2、代碼排查

排查過程中發現項目中並沒有類似分類服務調用及SQL查詢,是由於依賴的jar包中的方法有查詢數據庫,用的是本地緩存的形式,有個定時器類會從lion配置定時讀取信息,
緩存過期時間設置的是3600000s,
查到原因這個服務沒有人重新發布部署過,所以經過四十一天後緩存過期後,再初始化緩存時會重新讀數據庫獲取所有分類和城市的數據,兩次查詢分別獲取了六十多萬分類與城市對應關係的對象,由於數量多,申請堆空間過大,所以大量對象直接進入了老年代,觸發了fullGC
 

四、解決

這個方法是老的架構組件中方法並且已經很久沒人維護,後續這類商區服務的實現方式需要重構,去掉了本地緩存和直接讀取數據庫的方法,改爲分頁調用不是直接查緩存

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