當 Java 應用程式遭遇致命錯誤時,JVM 會在進程終止前自動生成兩份關鍵的診斷文件——JavaCore 與 HeapDump。這兩份文件猶如飛機的黑盒子,完整記錄了事故發生前的運行狀態。有趣的是,有時發生致命錯誤後應用並未立即崩潰,仍能勉強運行;但更多情況下,JVM 進程會直接退出。理解這兩份文件的區別與分析方法,是 Java 開發者排查疑難雜症的必修課。
JavaCore 關注「執行邏輯」(CPU 視角),HeapDump 關注「對象佔用」(記憶體視角)。
JavaCore 是純文本文件,核心內容是所有線程在特定時刻的堆疊追蹤。打開文件即可看到每個線程正在執行哪個類、哪個方法、哪一行代碼。通過對比不同時刻生成的多份 JavaCore,若發現同一線程長期停留在同一代碼位置(如資料庫查詢長期無響應),即可鎖定性能瓶頸或死鎖點。
HeapDump 是二進制文件,記錄特定時刻 JVM 堆中所有對象的詳細信息(類、屬性、引用關係等)。需借助 IBM Heap Analyzer、Eclipse MAT、VisualVM 等專業工具分析。其核心價值在於定位記憶體洩漏:找出佔用大量堆空間且無法被 GC 回收的對象,追溯其 GC Root 引用鏈。
當系統出現變慢、無響應等異常時,可手動生成診斷文件。建議間隔 10-30 秒連續生成 2-3 組,便於對比分析。
# 1. 找到 Java 進程 PID
ps -ef | grep java
# 2. 發送 SIGQUIT 信號 (kill -3) 觸發 JavaCore 生成
kill -3 <PID>
# 3. 等待片刻後再次執行,獲取第二組快照
kill -3 <PID>
注意: `kill -3` 並不會殺死進程,只是發送 `SIGQUIT` 信號請求 JVM 輸出線程快照。HeapDump 的生成通常需配合 JVM 參數(如 `-XX:+HeapDumpOnOutOfMemoryError`)或使用 `jmap -dump:format=b,file=heap.hprof
此法極其高效。若前後兩份 JavaCore 中,同一線程(如 `WebContainer : 5`)的堆疊頂端指向完全相同的代碼行,說明該線程在該處停留時間過長。結合業務日誌,可快速定位是資料庫鎖等待、外部 API 超時、還是死循環導致。
關鍵定位步驟:
Current Thread Details 區塊,獲取當前線程 ID(如 `sys_thread_t:0x45FB5328`)。4XESTACKTRACE 堆疊信息。使用 MAT (Memory Analyzer Tool) 打開 `.hprof` 文件:
Path to GC Roots → Exclude weak/soft references,追溯為何無法被回收。| 維度 | JavaCore | HeapDump |
|---|---|---|
| 文件類型 | 文本 | 二進制 |
| 核心內容 | 線程堆疊、鎖信息、JVM 參數 | 堆中所有對象實例、引用關係 |
| 適用場景 | CPU 高佔用、死鎖、線程阻塞、應用無響應 | OOM、記憶體洩漏、堆使用率持續增長 |
| 分析工具 | 文本編輯器、IBM Thread and Monitor Dump Analyzer | Eclipse MAT、VisualVM、JHat、IBM Heap Analyzer |
| 生成觸發 | SIGQUIT (kill -3)、JVM Crash | OOM、jmap、JVM 參數配置 |
建議生產環境常態化配置:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heapdumps/
並定期清理舊文件,避免磁盤佔滿。掌握雙快照對比分析 JavaCore,配合 MAT 深度剖析 HeapDump,將讓你從「無頭苍蠅」變為「故障偵探」。