首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

生產環境 OOM 救火實錄:IBM HeapAnalyzer 與 JCA 定位類加載器洩漏

     編輯:Java 相關知識

案例背景:反覆重啟的「止血」惡性循環

  • 系統規模:內網 500 用戶,高峰 440 並發
  • 硬體:AIX P570,4U/8G 分配給新系統
  • 架構:主備單節點,無叢集
  • 症狀:運行數小時後響應變慢,最終 OOM 宕機,被迫排程每日兩次重啟「釋放記憶體」

團隊嘗試過:SQL 優化(建索引、冗餘字段消除多表關聯)、OS/DB 參數調優、專家巡檢——均無效。最終通過分析 heapdump 與 javacore 定位根因。

工具鏈:IBM 兩大神器

工具用途獲取方式
HeapAnalyzer (ha36.jar)分析堆快照,找出佔用記憶體最大的對象alphaWorks
Thread and Monitor Dump Analyzer (jca37.jar)分析 javacore,識別死鎖、阻塞、類加載器洩漏IBM 支援站

啟動參數需分配足夠堆:

java -Xmx2000m -jar ha36.jar heapdump.phd
java -Xmx1000m -jar jca37.jar

HeapAnalyzer:初探無果

HeapAnalyzer 分析介面

結果顯示「載入對象過多」,但無法定位具體模組。因可讀性差、缺乏代碼層面關聯,陷入僵局。

JCA 破局:直指類加載器上限

JCA 啟動介面

分析 javacore.20090602.134015.430370.txt 關鍵發現:

Failure caused because the class loader limit was exceeded

JRE 版本:J2RE 5.0 IBM J9 2.3 (SR4, 2007-02-01)

Note:SR4 預設類加載器上限 8192,超過拋出 OOM。可用 -Xmxcl25000 提高上限。

JCA 分析結果第一部分

JCA 分析結果第二部分含 NOTE

根因追溯:定時任務觸發類爆炸

結合 Current Thread 名稱搜尋應用日誌,定位到某定時排程:

  • 功能:定時透過 DBLink 從外部庫抽取數據,轉換為 POJO 寫入內網庫
  • 邏輯:對每筆業務數據建立 10+ 個 POJO 組合
  • 觸發條件:單次抽取量稍大 → 瞬間創建大量類實例 → 類加載器計數超 8192

JCA 同時提供 GC 狀態、線程狀態詳細數據輔助驗證:

JCA 垃圾回收狀態分析

JCA 線程狀態分析

修復與驗證

在 JVM 啟動參數添加:

-Xmxcl25000

取消每日重啟排程,持續監控數周 —— 零 OOM 宕機。

事後補充:Grester v1.0.1 已發布至 Maven 中央倉庫,但 Jester 核心 JAR 仍需手動安裝。

最佳實踐總結

上線前整體規劃

  • 資源一次到位(避免中途調整資源導致重複調優)
  • 核心組件版本鎖定(JRE、DB 等),優先升級已知缺陷版本
  • 壓力測試必做,模擬真實業務峰值

攻堅團隊與工具箱

  • 組建核心攻堅小組(架構師、資深開發),授權直通決策
  • 預備分析工具鏈:HeapAnalyzer、JCA、VisualVM、MAT、Arthas 等
  • 建立故障現場保留機制(heapdump、javacore、GC log 自動收集)

心法:紙上得來終覺淺

半年攻堅,轉向 javacore 分析後一小時定位。工具不會說謊,關鍵在於:

  1. 不預設結構(先看 heapdump 失敗,轉 javacore 成功)
  2. 結合業務日誌交叉驗證
  3. 最小化變更驗證(僅加參數,不升級 JRE,降低風險)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved