一、工具總覽
| 工具 | 核心功能 | 典型場景 |
| jps | 列出本地 JVM 進程 ID (PID) 和主類名 | 定位目標進程,所有診斷的第一步 |
| jstat | JVM 統計監視:類加載、編譯、GC、內存分代使用情況 | 實時監控 GC 頻率、堆內存佔用、元空間變化 |
| jmap | 堆內存快照:對象統計、Heap Dump 導出 | 定位大對象、內存洩漏分析、導出快照給 MAT 分析 |
| jinfo | 查看/修改運行時 JVM 參數 | 驗證啟動參數生效情況、動態調整旗標 |
| jconsole | 圖形化監控:內存、線程、類、MBean 操作 | 可視化實時監控、遠程連接生產環境 |
| jstack | 線程快照:線程狀態、死鎖檢測、調用棧 | 定位死鎖、CPU 飆高線程、長時間阻塞點 |
二、標準診斷流程
# 1. 找到目標 PID
jps -l
# 輸出示例:
# 3024 com.example.Application
# 3025 org.apache.catalina.startup.Bootstrap
# 2. 選擇 PID 進行後續診斷,如 3024
三、jstat 參數詳解(最強監控工具)
常用參數組合
# GC 統計:次數、耗時
jstat -gc 3024 1000 10
# 每 1 秒採樣 1 次,共 10 次
# 輸出欄位:S0C S1C EC OC MC YGC YGCT FGC FGCT GCT
# 內存分代容量
jstat -gccapacity 3024
# 新生代詳情
jstat -gcnew 3024
# 老年代詳情
jstat -gcold 3024
# 元空間詳情
jstat -gcpermcapacity 3024 # JDK 7/8
jstat -gcmetacapacity 3024 # JDK 8+
# 綜合利用率
jstat -gcutil 3024 1000 10
# 編譯統計
jstat -compiler 3024
# 類加載統計
jstat -class 3024
關鍵欄位含義
| 欄位 | 含義 |
| S0C/S1C | Survivor 0/1 容量 (KB) |
| EC/OC | Eden/Old 區容量 (KB) |
| MC/CCSC | Metaspace/Compressed Class Space 容量 (KB) |
| YGC/YGCT | Young GC 次數 / 累計耗時 (秒) |
| FGC/FGCT | Full GC 次數 / 累計耗時 (秒) |
| GCT | GC 總耗時 (秒) |
四、jmap 實戰命令
# 1. 存活對象統計(按類統計數量、大小)
jmap -histo:live 3024 | head -30
# 2. 導出堆快照(二進制格式,供 MAT 分析)
jmap -dump:format=b,file=heap.bin 3024
# 文件較大,建議生產環境低峰期操作
# 3. 查看堆配置與使用情況
jmap -heap 3024
五、jinfo 參數查看與動態修改
# 查看所有參數
jinfo -flags 3024
# 查看具體參數值
jinfo -flag MaxMetaspaceSize 3024
jinfo -flag HeapDumpOnOutOfMemoryError 3024
# 動態修改可管理參數
jinfo -flag +HeapDumpOnOutOfMemoryError 3024 # 開啟
jinfo -flag -PrintGCDetails 3024 # 關閉
六、jconsole 圖形化監控
- 命令行輸入
jconsole 啟動 GUI
- 選擇本地進程或遠程連接:
host:port(需啟動 JMX:-Dcom.sun.management.jmxremote)
- 核心頁籤:
- 內存:堆/非堆使用趨勢、GC 觸發手動按鈕
- 線程:線程數趨勢、死鎖檢測、堆棧追蹤
- 類:加載/卸載類數量
- MBeans:操作 JMX Bean(如動態修改 Log Level、觸發 GC)
JConsole 內存區域對照
| JConsole 顯示 | JVM 內存區域 | 說明 |
| Eden Space | Heap - Young Gen | 新對象分配區 |
| Survivor Space | Heap - Young Gen | GC 後存活對象 |
| Tenured Gen | Heap - Old Gen | 長期存活對象 |
| Perm Gen / Metaspace | Non-Heap | 類元數據、常量池 |
| Code Cache | Non-Heap | JIT 編譯代碼緩存 |
七、jstack 線程診斷
# 基礎線程快照
jstack 3024 > thread_dump.txt
# 強制輸出(進程掛起時)
jstack -F 3024
# 定時多次採樣(排查 CPU 高)
for i in {1..5}; do jstack 3024 > dump_$i.txt; sleep 2; done
關鍵線程狀態
RUNNABLE:正在執行/可執行(CPU 高關注點)
BLOCKED:等待監視器鎖(同步塊/方法)
WAITING:無限等待 (Object.wait(), Thread.join())
TIMED_WAITING:限時等待 (sleep, wait(timeout))
死鎖自動檢測
輸出末尾會有 Found one Java-level deadlock 區塊,列出死鎖線程及鎖對象。
八、進階分析工具:Eclipse MAT
- 官網:https://www.eclipse.org/mat/
- 核心功能:支配者樹 定位 GC Root 引用鏈、直方圖 統計對象大小、OQL 查詢 精準定位洩漏對象
- 典型流程:
jmap -dump → MAT 打開 → Histogram 按 Retained Heap 排序 → 右鍵 Merge Shortest Paths to GC Roots → 找到洩漏引用鏈
九、常用組合拳
| 問題 | 診斷組合 |
| 頻繁 Full GC | jstat -gcutil PID 1000 → jmap -histo:live PID → MAT 分析大對象 |
| CPU 100% | top -H -p PID 找線程 ID → printf "%x" TID → jstack PID grep 十六進制 TID |
| OOM | 啟動參數 -XX:+HeapDumpOnOutOfMemoryError → 事後 MAT 分析 heap.bin |
| 應用無響應 | jstack 多次採樣對比 → 找長期 BLOCKED/RUNNABLE 熱點代碼 |
原文參考:https://boendev.iteye.com/blog/882479