全功能 GUI 分析器(JConsole、VisualVM、JProfiler)雖然強大,但在生產環境中往往因開銷過大、需圖形介面、或權限受限而難以部署。JDK 內建的命令列工具(jps、jstat、jstack、jmap、jhat)無需額外安裝、開銷極低、可通過 SSH 遠程執行、支援腳本自動化,是「生產環境第一現場」排查性能問題的首選武器庫。
jps (JVM Process Status) 列出本機所有 Java 進程的 VMID(不等同於 OS PID)及啟動主類名稱。
$ jps -lvm
12345 com.myapp.Main -Xms2g -Xmx4g -Dconfig=prod.yml
67890 org.apache.catalina.startup.Bootstrap start
-l:顯示完整主類名(或 JAR 路徑)。-v:顯示 JVM 參數。-m:顯示傳給 main() 的參數。提示:若進程未顯示,可能未啟用 -Dcom.sun.management.jmxremote 或權限不足。
jstat 以固定間隔採樣輸出 GC、類載入、JIT 編譯等統計。常用選項:
| 選項 | 用途 | 關鍵欄位 |
|---|---|---|
-gc | GC 行為總覽 | S0C, S1C, EC, OC, MC, YGC, FGC, GCT |
-gcutil | 空間使用率百分比 | S0, S1, E, O, M, CCS, YGC, FGC, FGCT, GCT |
-gccapacity | 各代容量上限 | NGCMN, NGCMX, OGCMN, OGCMX, MCMN, MCMX |
-class | 類載入/卸載統計 | Loaded, Bytes, Unloaded, UBytes, Time |
-printcompilation | JIT 編譯熱點方法 | Compiled, Size, Type, Method |
# 每 250ms 採樣一次 GC,共 10 次
jstat -gc 12345 250 10
# 長期監控類載入洩漏(每 5 秒輸出一次,無限循環)
jstat -class 12345 5000
jstack <vmid> 輸出所有 Java 線程堆疊,相當於 kill -3 或 Ctrl+Break。
-l:顯示鎖資訊(關鍵:定位死鎖、Object.wait() 長時間阻塞)。-F:強制執行(進程掛起時)。"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f... nid=0x1234 waiting for monitor entry [0x00007f...]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.example.Deadlock.methodA(Deadlock.java:15)
- waiting to lock <0x000000076b2c1e80> (a java.lang.Object)
- locked <0x000000076b2c1e90> (a java.lang.Object)
配合 grep -A 20 "BLOCKED" 快速鎖定問題線程。
# 格式:jmap -dump:[live],format=b,file=<path> <vmid>
jmap -dump:live,format=b,file=/tmp/heap.hprof 12345
live:僅保留存活對象(觸發 Full GC,生產環境慎用)。.hprof 可用 jhat、VisualVM、Eclipse MAT、JProfiler 分析。jmap -histo 12345 | head -30
輸出:類名、實例數、總大小(bytes)。可快速發現 char[]、String、集合類洩漏。
jhat -port 7000 /tmp/heap.hprof 啟動內建 HTTP 伺服器,瀏覽器訪問 https://localhost:7000。
# 查找長度 > 100 的 String
select s from java.lang.String s where s.count >= 100
# 查找所有引用 java.io.File 的對象
select referrers(f) from java.io.File f
注意:大型堆 (>4GB) 分析極慢,建議改用 Eclipse MAT 或商業工具離線分析。
jps 確認目標 VMID。jstat -gcutil 觀察 GC 頻率、老年代增長趨勢。jstack -l 找 BLOCKED/RUNNABLE 熱點線程。jmap -histo 定位可疑類 → jmap -dump 導出 → 離線分析。jstat -class 監控 Loaded/Unloaded 差值。這五大工具雖被標註為「實驗性/不穩定」,但經過十餘年生產環境考驗,已成為 Java 運維排障的「標準急救箱」。熟練掌握它們,能在無 GUI、無權限安裝第三方工具的受限環境中,快速定位 80% 以上的性能問題。