1. 程式人生 > >java記憶體洩漏問題排查

java記憶體洩漏問題排查

      前些日一直在忙效能測試和效能調優,發現效能基本滿足要求了,但是出現一個很詭異的問題,我分配給JVM記憶體10G記憶體系統能夠跑兩天,如果分配2個G記憶體也就跑3個小時,據測試的同事反應在不停的效能測試時系統宕機時間很有規律,而且這個問題持續了有一段時間了,同事也在不停地review程式碼也沒找到蛛絲馬跡,正好有時間所以我決定徹底跟蹤一下這個問題,經過兩天的不斷摸索,終於查到原來還是某同事使用MAP時只負責了存資料,而沒有釋放,從而導致記憶體洩漏,最終JVM記憶體被完全耗光,而fullGC在不斷嘗試時回收不回來任何記憶體,最終導致系統執行緩慢,記憶體溢位,從而宕機。

總結一下我的排查步驟:

1、首先我把JVM記憶體調小,便於在最短的時間內發現問題,利用jstat觀察JVM記憶體回收的情況和使用情況,期間發現舊生代記憶體的申請在一直進行,但是GC基本回收不回來記憶體,所以很堅信如果JVM沒有BUG的情況下,肯定是存在記憶體洩漏的地方,應該是程式碼有問題。但是如何在不翻遍整個程式碼的情況下,定位問題呢?

2、我查閱幾個JVM記憶體匯出工具,並利用JMAP把JVM全部匯出來,但是發現悲催的溫鬥士下,這些工具根本打不開一個G左右的匯出檔案,直接報亂七八糟的錯誤,可能也是我的PC硬體配置不高吧,無奈之下只好找了一臺LINUX伺服器,在其上裝了MAT工具,然後把JVM匯出檔案放到這臺伺服器上進行分析,結果迅速定位到了存在問題的程式碼

JMAP匯出JVM命令格式如下:

jmap -dump:live,format=b,file=heap.bin <pid>

MAT使用比較簡單,不再介紹,只要選擇開啟匯出的檔案即可對哪些物件、類等對記憶體的使用情況一目瞭然,從而幫助把有可能出問題的程式碼範圍儘量縮小,不用像大海撈針一樣採用人海戰術逐行程式碼排查。