現象
發現項目運作一段時間後會莫名其妙的不運作了,沒有任何異常日志,好像被hung住了一樣,不工作了。
排查
1、首先檢視GC日志,通過
jstat -gcutil -t pid 1000 1000
檢視GC日志,看到FullGC的次數達到了接近兩萬次。。。并且GC速率沒有下降的趨勢。
2、又通過
jmap -heap pid
檢視堆記憶體情況,發現Old區Free剩餘2M。。
3、通過
jmap -hsito pid
檢視哪些類占用的空間多,看到我們自定義的一個類占用很大,是以定位到是我們項目的代碼問題。
4、通過
jmap -dump:format=b,file=xxxx.hprof
Dump下我們的堆記憶體日志,通過MAT記憶體分析工具分析日志。檢視到MAT幫助分析出來的兩個問題。
第一個為jdbc的
JDBC42ResultSet
,其所占用的堆記憶體大小為48.97%,但是Details中并看不到什麼有用的資訊,是以看另外一個問題,另外一個問題是在一個線程中,進入Details中檢視詳細資訊。
通過詳細資訊可看到線程名為task-1的線程中,有一個List,List中有N個我們自定義的類對象,與上邊檢視類占用記憶體所檢視到類為同一個類,是以确定問題在這裡出現,因為線程名為tast-1,我們設定的Spring Schedule的線程名稱字首為
task-
,再次檢視Thread Stack可以定位到具體調用的代碼位置,其中有一個定時任務為将表中部分資料取出來進行視訊下載下傳的操作,由于網速慢,導緻線程一直在執行,并且由于配置原因,定時任務執行頻率為4s一次,由于我們的list的循環并沒有執行結束,引用一直在,是以不能被回收掉,導緻old區占滿,是以調整定時任務執行頻率,問題解決。