天天看點

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

本期分享專家:濱雨,有多年軟體開發 + 項目管理經驗,先後在華為、阿裡基礎架構部任職,在阿裡雲主要從事存儲、cdn、視訊、中間件等技術領域的支援,喜歡新技術,喜歡鑽研,喜歡各種新的挑戰。

相信很多“程式猿”都能知道,oom 異常,就是我們常見的: “java.lang.outofmemoryerror” 在應用開發中,是比較常見的一種異常,主要分為三種:

1. outofmemoryerror: permgen space

2. outofmemoryerror: java heap space

3. outofmemoryerror:unable to create new native thread

出現oom的情況,往往會導緻:

1、應用服務異常

2、線程異常

3、程式崩潰

以及其他未知的問題,相信看到這幾點就能體會到 “ oom ” 的“ 恐怖 ”了。

在遇到這oom問題的時候,要如何分析原因,是直接去死磕代碼?還是去調整工程架構?我相信這樣的方式很多時候都隻會徒勞,那針對這類問題,我們可以如何快速的去排查定位呢?

為了說清楚整個排查過程,我們編寫一段outofmemoryerror測試代碼,用來模拟出 oom 場景。

servlet 測試代碼:

web.xml映射路徑:

dump檔案是程序的記憶體鏡像,可以把程式的執行狀态通過調試器儲存到dump檔案中,是開發人員定位jvm問題的“利器”。

通過edas控制台部署啟動應用,可以指定jvm參數,在控制台上指定最大heap size 和初始化heap size 都為100m  (注意現在配置的值隻是為了測試),

另外還可以自定義加上一些參數,例如:

控制台上設定:

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結
EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

printgcdetails 會将gc日志列印出來,xx:heapdumppath指定dump檔案存儲路徑,當出現oom問題時,會在/home/admin/dump/生成一個dump檔案

jmap 是 jdk自帶的一個 jvm 檢測工具,為了能讓通過jmap方式的時候擷取到堆棧溢出的dump檔案,我們将代碼改為:

通路到測試代碼入口,在應用伺服器上執行:

可以擷取到heap.bin檔案。

admin使用者登入到伺服器上,找到tomcat程序id,執行 ./jstat -gcutil {pid} {時間間隔} ,觀察 gc 執行情況:

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

可以看到目前ygc 和 fgc 都不頻繁,屬于正常狀态。

當我們通路測試路徑: http://{ip}:port/path/heap.htm

執行結束後,可以發現,eden 區和 old 區 都瞬間打滿,而且短時間内發生多次 fgc:

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

到伺服器上,之前我們指定的路徑下面,方式一:/home/admin/dump/ 可以找到生成的 hprof 檔案,方式二:生成的heap.bin檔案,下載下傳下來後,用 mat 記憶體分析軟體打開

EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結
EDAS——如何快速定位OOM問題 什麼是OOM?OOM的危害如何排查OOM問題小結

經過mat 分析後,馬上可以得出一份分析報告,從這可以很清晰的定位到,是由于 “ heapoutofmemory.doget ” 這段代碼入口導緻的堆棧溢出,終于,我們的“罪魁禍首”付出水面了,原來,是由于代碼中出現了一段死循環一直在建立class 類,導緻堆棧溢出,接下來,該知道怎麼去修改代碼了吧。

當遇到jvm問題的時候,不必驚慌,也不要因為是技術底層問題而感到無從下手,我們有很多種方法可以友善定位到原因,除了本文中提到的 mat 記憶體分析工具,我們還有很多其他的小工具可以利用起來,jdk 本身就提供了很多這樣的支援工具,例如: jconsole、jmap、jstat、jinfo、jvisualvm 等等,會利用好這些小工具,下次再遇到類似的問題後,就可以得心應手了。

<a href="https://www.atatech.org/articles/75628#comment">評論文章 (0)</a>