一次關於Netty+Gson造成記憶體洩露 Memory Analysis分析
第一步:
jmap -dump:format b,file=abc.hprof <pid>
dump出記憶體日誌
第二部:
使用Memory Analysis開啟abc.hpro
從上圖可以看到,洩露記憶體部分佔用了快500M了。而整個應用也就分配了500M。
從直方圖可以看到,前五位物件已經佔用了快300M的記憶體。所以我們焦點放在這裡,去排查記憶體洩露點。
從上圖可以看到,9個執行緒物件很平均地佔用了50M左右的記憶體。那我們隨機取一個NIO執行緒物件出來分析。
從上圖可知,一個執行緒只佔用極小記憶體,但是它卻引用了非常大量的其他物件,而且不能釋放掉。
這些物件,最終是被本地執行緒變數MAP所引用。
在直方圖上,我們 選擇第一條,右鍵“list objects”下選擇“with incoming references”
從下圖可知,這些物件都是被一些業務資料bean所引用
在直方圖上,我們 選擇第一條,“Path to GC Roots”->"exclude weak references"
從垃圾回收路徑看到,本地執行緒變數所儲存的資料,最終還是由gson類所引用業務資料。
到這裡,我們就可以針對所有使用gson的地方進行排查了。
總結:通過兩種不同方法對同一個記憶體洩露現象進行分析,我們可以看到,其實使用java自帶工具進行分析,完全能夠快速定位問題所在,因為特徵資訊很明顯。特別是對系統比較熟悉的情況下,完全可以出奇制勝,一步到位。使用MAT,我們可以更直觀和看到更豐富的資訊。甚至豐富到影響你的排查。:)
在當前這個案例來看,MAT並不能體現出多大的優勢。但如果洩露特徵資訊不明顯的情況下,MAT還是具有很強大的樹狀記憶體追蹤能力的。
記憶體洩露分析,難點在於沒有統一、固定的分析解決方法,全靠的是經驗、分析能力、對系統的熟悉和感覺!