Contents

使用 AIX IBM HeapAnalyzer 查詢 Java OOM 問題

最近接的案子有遇到 Java OOM。這種問題最麻煩的地方在於,看到 OutOfMemoryError 不代表你立刻就知道是哪一段程式出了問題。很多時候只是 JVM 已經爆了,但真正的根因可能是某個查詢撈太多資料、某個快取沒有釋放,或某個流程在短時間內開了太多執行緒。

如果環境是在 AIX,而且用的是 IBM 的 JVM,還會多一個落差:很多常見教學都在講 hprof 或 HotSpot 工具,但 AIX / IBM JVM 常見拿到的是 .phd dump。這時候就不能直接照一般教學走,要改用 IBM HeapAnalyzer 這類工具來看。

先講 OOM 排查不要只看 dump

Heap dump 很重要,但它只是拼圖的一塊。真正查 OOM,我會至少同時看這幾樣:

  • 應用程式 log
  • GC log
  • thread dump / javacore
  • heap dump
  • 事故發生時間點附近的業務操作

原因很簡單:heap dump 告訴你「當下記憶體裡塞了什麼」,但不一定直接告訴你「為什麼塞了那麼多」。

AIX / IBM JVM 跟一般教學哪裡不一樣

在 Oracle HotSpot 或 OpenJDK 的文章裡,常會看到 .hprof。但在 AIX 上,如果是 IBM J9 / OpenJ9 相關環境,實務上常拿到的是 .phd 檔案與 javacore

這也是我一開始卡住的地方:

  • dump 有產生
  • 但平常常見的分析工具不一定直接好用
  • 搜尋一輪後才發現要改找 IBM HeapAnalyzer

工具連結:

基本排查流程

我自己的處理順序大概是下面這樣:

  1. 先從 log 確認 OOM 發生時間與錯誤型態。
  2. 確認當下有沒有產出 .phdjavacore 或其他 dump。
  3. 用 IBM HeapAnalyzer 開 .phd
  4. 看大物件、可疑類別、物件保留鏈。
  5. 再回頭對照 log 與業務流程,找出真正是哪段功能把 heap 撐爆。

IBM HeapAnalyzer 可以看什麼

打開 .phd 後,通常我會優先看幾件事:

  • 哪些類別佔了最多記憶體。
  • 哪些物件數量異常多。
  • 某個大物件是被誰 reference 住。
  • 是否存在明顯的集合類別暴增,例如 ArrayListHashMap、快取容器等。

下面幾張圖是當時分析時的畫面紀錄。

01.avif

02.avif

03.avif

04.avif

看圖時我會怎麼判讀

HeapAnalyzer 能幫你很快看出「現在 heap 裡最肥的是誰」,但它不一定會直接跳出一句話告訴你「第幾行程式碼有問題」。所以判讀的關鍵還是在交叉比對。

例如你看到某個集合佔很大,就要繼續問:

  • 這個集合屬於哪個模組?
  • 它是暫存查詢結果,還是快取?
  • 為什麼它沒有在預期時間內釋放?
  • 是單筆物件太大,還是筆數太多?

很多時候,問題不是單一類別寫得很差,而是某段業務流程在錯的時間撈了太多資料。

這次實際查到的狀況

我這次碰到的情況,不是單純某個類別無限成長,而是程式本來會依 MQ 訊息開對應執行緒做處理。剛好同時間有兩支流程一起跑,其中一支會大量查資料,把 JVM heap 直接撐爆。

也就是說,真正的問題比較接近:

  • 併行處理下,某個工作量太大。
  • 單次查詢回來的資料量過多。
  • 多條執行緒同時做重型工作,導致總記憶體快速升高。

最後的處理方式,不是單純加大 heap 就結束,而是先把那個重型排程移出去,避免它跟其他流程同時搶 JVM 記憶體。

我會特別再查的幾個方向

如果你也遇到類似問題,可以順手再確認:

  1. SQL 是否一次撈太多資料。
  2. 結果集有沒有全部先載入記憶體。
  3. 執行緒池大小是否合理。
  4. 快取是否設上限。
  5. 是否有大批次檔案、訊息或報表在同一時間集中處理。

因為很多 OOM 的根因其實不是「洩漏」,而是「設計上允許某段流程一次吃太多記憶體」。

心智圖

mindmap root((AIX Java OOM 排查)) 事故資料 應用程式 log GC log javacore heap dump AIX 特性 IBM JVM PHD dump 不是常見 HPROF 分析工具 IBM HeapAnalyzer 大物件 類別佔用 reference chain 根因方向 大量查詢 併行執行緒 快取過大 集合暴增 修正方式 移出重型排程 限制資料量 調整併行數

小結

在 AIX 上查 Java OOM,最大的差別是工具鏈要換一下思維,不是直接照一般 .hprof 教學走。IBM HeapAnalyzer 可以幫你找到 heap 裡哪些物件最可疑,但真正定位根因,還是要把 dump、 log、查詢行為與執行緒活動一起看。

這次我最後學到的重點是:不要太快把 OOM 當成單純的 JVM 參數問題,很多時候它反映的是業務流程和資料量的組合出了問題。

延伸參考: