生產環境 JVM 故障診斷,javacore (Thread Dump) 與 heapdump 是兩大核心藍圖。前者聚焦 CPU/執行緒狀態,後者聚焦記憶體/物件分佈。本文系統解析生成時機、獲取方法、分析工具與實戰診斷流程。
| 維度 | Java Core Dump (javacore.txt) | Heap Dump (heapdump.phd) |
|---|---|---|
| 核心關注 | CPU、執行緒、鎖、堆疊 | 記憶體、物件、類、GC 根 |
| 檔案格式 | 文本 (可直接閱讀) | 二進制 (需專用工具) |
| 檔案大小 | 小 (KB~MB) | 大 (GB 級,約等於 Heap 大小) |
| 生成觸發 | SIGQUIT (kill -3)、OutOfMemoryError、手動 API | OutOfMemoryError、手動 API、JMap |
| 主要用途 | 死鎖、CPU 飆高、卡頓、無回應 | 記憶體洩漏、OOM 原因、物件保留路徑 |
| 分析工具 | 編輯器、IBM Thread Monitor、fastThread、TDA | Eclipse MAT、IBM Heap Analyzer、JHat、JVisualVM |
# 1. 找出 Java 進程 PID
ps -ef | grep java
# 範例輸出: root 5580 1 0 Oct27 ? 00:02:27 /usr/bin/java -server ...
# 2. 發送 SIGQUIT 信號 (產生 javacore + 可能 heapdump)
kill -3 5580
# 3. 間隔 10-30 秒再發送一次 (對比兩份 javacore 找卡點)
sleep 20
kill -3 5580
# 4. 指定輸出目錄 (IBM JVM)
# -Xdump:java:defaults:file=/path/to/javacore.txt
# -Xdump:heap:defaults:file=/path/to/heapdump.phd
# jstack - 執行緒堆疊 (相當於 javacore)
jstack -l > thread_dump.txt
jstack -F > thread_dump.txt # 強制模式 (進程掛起時)
# jmap - 堆轉儲
jmap -dump:live,format=b,file=heapdump.hprof # 只存活物件
jmap -dump:format=b,file=heapdump.hprof # 全部物件
# jcmd - 診斷命令工具 (JDK 7+)
jcmd Thread.print > thread_dump.txt
jcmd GC.heap_dump heapdump.hprof
// 1. 觸發 Thread Dump (HotSpot)
ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
// 2. 觸發 Heap Dump (需 com.sun.management.HotSpotDiagnosticMXBean)
HotSpotDiagnosticMXBean mxbean = ManagementFactory.newPlatformMXBeanProxy(
ManagementFactory.getPlatformMBeanServer(),
"com.sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean.class);
mxbean.dumpHeap("/path/heapdump.hprof", true); // live=true
# OOM 時自動生成
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/dumps/heapdump.hprof
# IBM JVM 參數
-Xdump:heap:events=systhrow,filter=java/lang/OutOfMemoryError
-Xdump:java:events=systhrow,filter=java/lang/OutOfMemoryError
Current Thread Details 或 1XHCURRENTTHD (IBM) / "main" #1 (HotSpot)4XESTACKTRACE (IBM) 或 at com.xxx.Class.method (HotSpot)BLOCKED / WAITING → 鎖爭用、等待資源RUNNABLE + I/O → 磁碟/網路慢Object.wait() / Thread.join() / Thread.sleep() → 正常等待或卡住java.lang.OutOfMemoryError 在標題 → 直接看 Heap Dump-- 找超過 10MB 的集合
SELECT * FROM java.util.ArrayList WHERE (toHexString(size) >= 1000000)
-- 找特定類別實例保留路徑
SELECT * FROM com.myapp.CacheEntry
| 現象 | Core Dump 特徵 | Heap Dump 特徵 | 典型原因 |
|---|---|---|---|
| CPU 100% | 多執行緒 RUNNABLE、堆疊在計算/正則/序列化 | 無特徵 | 死迴圈、低效演算法、GC 狂轉 |
| 應用無回應 | 執行緒 BLOCKED/WAITING、同一鎖/資源 | 可能正常 | 死鎖、連線池耗盡、外部服務超時 |
| OOM: Java Heap | 標題含 OOM | 大量特定類實例、集合無限增長 | 快取無清理、集合未釋放、記憶體洩漏 |
| OOM: Metaspace | 標題含 OOM | 大量 Class/ClassLoader | 類加載器洩漏、動態生成類過多 |
| GC 頻繁/停頓長 | VM Thread/GC Thread 活躍 | 大量短命物件、老年代碎片 | 分配率高、大物件、Heap 太小 |
jstack、jmap 建立基準線fastThread、MAT 命令列分析kubectl exec 進容器生成、Sidecar 定期收集掌握雙 Dump 獲取、分析工具鏈、模式識別,是 JVM 故障從「有感覺」到「有證據」的關鍵能力躍升。