線上問題定位--OOM
伺服器上部署了Java服務,出現了OutOfMemoryError,問題應該如何定位?
解決思路
Java服務OOM,最常見的原因為:
-
有可能是記憶體分配確實過小,而正常業務使用了大量記憶體
-
某一個物件被頻繁申請,卻沒有釋放,記憶體不斷洩漏,導致記憶體耗盡
-
某一個資源被頻繁申請,系統資源耗盡,例如:不斷建立執行緒,不斷髮起網路連線
更具體的,可以使用以下的一些工具逐一排查。
一、查發生了OOM的程序
工具:top
方法:
-
執行top -d 1 -c,每秒重新整理一次,顯示程序執行資訊列表
-
鍵入M (大寫m),程序按照記憶體使用排序
圖示:
二、確認是不是記憶體本身就分配過小
方法:jmap -heap 2820
如上圖,可以檢視新生代,老生代堆記憶體的分配大小以及使用情況,看是否本身分配過小。
三、找到最耗記憶體的物件
方法:jmap -histo:live 2820 | more
圖示:
如上圖,輸入命令後,會以表格的形式顯示存活物件的資訊,並按照所佔記憶體大小排序:
-
例項數
-
所佔記憶體大小
-
類名
是不是很直觀?對於例項數較多,佔用記憶體大小較多的例項/類,相關的程式碼就要針對性review了。
上圖中佔記憶體最多的物件是byte,共佔用記憶體71M,值得關注,後續再MAT中再次分析。
四、確認是否是資源耗盡
檢視程序建立的執行緒數,如果資源耗盡,也可能出現OOM。
工具:
-
ps
方法:ps -efL 2820
檢視程序網路連線數,如果資源耗盡,也可能出現OOM。
工具:
-
netstat
方法:netstat -apn | grep 2820
這裡介紹另一種方法,通過
-
/proc/${PID}/fd
-
/proc/${PID}/task
可以分別檢視控制代碼詳情和執行緒數。
例如,某一臺線上伺服器的sshd程序PID是2820,檢視
-
ll /proc/2820/fd
-
ll /proc/2820/task
喜歡請微信掃描下面二維碼,關注我公眾號--“扯一扯技術”,做一些實戰專案中的問題和解決方案分享。