線上問題定位--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 

 

喜歡請微信掃描下面二維碼,關注我公眾號--“扯一扯技術”,做一些實戰項目中的問題和解決方案分享。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM