OOM內(nèi)存泄露速查備忘錄
本文整理了一份OOM內(nèi)存泄露問(wèn)題速查備忘錄,詳細(xì)見(jiàn)下文。
1、核心步驟
- top、free、df三連,查看CPU、內(nèi)存、磁盤(pán)的大致情況。
- netstat -lp 查看端口占用情況。
- 導(dǎo)出內(nèi)存dump文件:
# 保存了堆內(nèi)存現(xiàn)場(chǎng)
jmap -dump:format=b,file=heap.dump pid
# 強(qiáng)制保存了堆內(nèi)存現(xiàn)場(chǎng)
jmap -F -dump:format=b,file=heap.dump pid
- 保存線程棧:
# 保存了線程棧的現(xiàn)場(chǎng)
jstack pid > jstack.log
2、輔助工具
- jstat -gc[gcutil] pid [interval]查看JVM垃圾回收情況。通過(guò) jstat 查看 GC 信息,首先就是判斷 GC 時(shí)間是否較長(zhǎng),GC 發(fā)生是否頻繁,然后看是否經(jīng)常性進(jìn)行 FullGC。
# 如:jstat -gc pid 1000,持續(xù)跟蹤如1S一次。查看java堆的狀況,顯示具體數(shù)值。
jstat -gc pid 1000
# 通過(guò) jstat -gcutil 5 1000命令查看GC信息,其中5代表進(jìn)程號(hào),1000代表顯示時(shí)間。查看堆中各個(gè)區(qū)域已使用空間占其總空間的百分比。
jstat -gcutil pid 1000
- 借助MAT(Eclipse Memory Analyzer)工具分析dump文件,分析內(nèi)存情況。
- 直接用文本工具打開(kāi)jstack文件,分析線程占用情況。
- 借助VisualVM更直觀:
3、分析過(guò)程
3.1、分析線程棧
直接通過(guò)文本工具打開(kāi)jstack.log,搜索業(yè)務(wù)相關(guān)包名,應(yīng)該大致能定位出問(wèn)題:
3.2、分析內(nèi)存
1. 用MAT工具打開(kāi)dump文件
2. 一般打開(kāi)Histogram視圖,這樣能快速地發(fā)現(xiàn)問(wèn)題,也可以打開(kāi)Leak Suspects(泄露嫌疑),如下圖:
尋找這個(gè)對(duì)象被哪些地方引用了,如下圖:
查看大對(duì)象,找出自己業(yè)務(wù)相關(guān)的關(guān)鍵引用:
根據(jù)上面GC Roots的結(jié)果,在結(jié)合自身的業(yè)務(wù)代碼排查下,一般都會(huì)找到線索,比如:
- 某個(gè)線程遠(yuǎn)程調(diào)用了接口返回的對(duì)象,一直被使用未能釋放
- 每次執(zhí)行的數(shù)據(jù)量過(guò)大
- 流沒(méi)有關(guān)閉
- 死循環(huán) 或者 遞歸次數(shù)太多
- 定時(shí)任務(wù)執(zhí)行頻率過(guò)高,在任務(wù)沒(méi)執(zhí)行完畢時(shí)又在持續(xù)執(zhí)行,導(dǎo)致積壓了大量對(duì)象
- ......
4、總結(jié)
本文整理了一份OOM內(nèi)存泄露問(wèn)題速查備忘錄。核心內(nèi)容是:
- top、free、df三連,然后netstat、jstat工具跟上。
- 緊接著趕緊jmap、jstack保存現(xiàn)場(chǎng),然后重啟應(yīng)用。
- MAT分析問(wèn)題,修改問(wèn)題,重新發(fā)布。