記錄一次sharingjdbc引起的fullgc頻繁問題,總結一下fullgc頻繁解決的方案

背景:最近做了個需求,爲了優化效率所以做了本地緩存和redis緩存,這個跟實際問題沒有很大關係,但在排查問題時造成了一定的干擾,導致排查時間變長了,這個問題的現象是上線後cpu急劇增高,fullgc次數比younggc次數多,而且每次fullgc回收的內存很少,fullgc頻繁。
1.問題現象圖:
在這裏插入圖片描述
在這裏插入圖片描述
2.分析:通過gc的情況可以看出一直在進行fullgc而沒有進行younggc,這種情況猜測是有大對象執行進入了老年代,而且在老年代回收時沒有被回收掉,正好代碼裏也使用的本地緩存,在上之前是有計算本地緩存會佔多大內存的,通過計算是不可能成爲大對象,但出問題了也只能試試了,下面是解決問題的思路。
2.1把本地緩存減小,上一版之後觀察了半小時沒出問題,以爲改好了,但過了一段時間又出現了。
2.2把本地緩存都去掉,上一臺服務器之後觀察了一下午沒出問題,此時認爲終於可以了,全量之後不久出問題。
2.3到此時就很頭痛了,不知道從何下手,因爲服務器的內存有14G,使用jmap命令dump下來文件過大,在本地分析不了內存情況,幸好此時同事提供一個命令:jmap -histo:live pid | head -n 100 // 查詢前100個內存使用過高的java類,使用此命令一看才發現真正的問題所在:
在這裏插入圖片描述
這個SQLIgnoreExpression說明sharingjdbc在執行sql報錯了,在報錯之後不停的在創建這個對象。然後再通過打印sql發現in裏面有個空list。查看代碼:
在這裏插入圖片描述
這個地方沒有判空,這也算是sharingjdbc的一大坑,集合一定要判空,所以in操作都判空之後就沒有問題了。
總結:通過此次事件發現jmap -dump:format=b,file=e.bin pid這個命令的侷限性了,因爲一般生產上的內存都挺大,dump下來本地根本就分析不了,感覺jmap -histo:live pid | head -n 100 // 查詢前100個內存使用過高的java類這個命令還是挺好使的,可以快速的找個大對象。

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