Contents

JVM 查看記憶體使用情況方法

監控 JVM 記憶體使用狀況是 Java 應用程式效能調優的基礎。本文整理常用的 JVM 記憶體查看工具,從命令列工具到圖形化介面,以及 JVM 記憶體各區域的說明。

JVM 記憶體架構概述

在查看工具之前,先了解 JVM 記憶體的主要區域:

Heap(堆積記憶體)

GC 管理的主要區域,儲存物件實例:

  • Eden Space:新建物件首先分配在這裡
  • Survivor Space(S0/S1):Minor GC 後存活的物件移到這裡
  • Old Generation(Tenured):存活多次 GC 的長壽物件
  • (Java 7 以前)Permanent Generation:Class 資訊、常數池

Non-Heap

  • Metaspace(Java 8+):Class 定義、方法資訊(取代 PermGen,使用原生記憶體)
  • Code Cache:JIT 編譯後的機器碼
  • Thread Stack:每個執行緒的方法呼叫堆疊

命令列工具

jps — 查看 Java 程序

1
2
# 列出所有 Java 程序的 PID 和名稱
jps -l

輸出範例:

1
2
12345 com.example.MyApp
67890 org.apache.catalina.startup.Bootstrap

jstat — 即時 GC 統計

1
2
# 每 1000ms 輸出一次 GC 統計,共 10 次
jstat -gc <pid> 1000 10

主要欄位說明:

欄位 說明
S0C/S1C Survivor 0/1 容量(KB)
S0U/S1U Survivor 0/1 使用量(KB)
EC/EU Eden 容量 / 使用量(KB)
OC/OU Old Gen 容量 / 使用量(KB)
MC/MU Metaspace 容量 / 使用量(KB)
YGC/YGCT Minor GC 次數 / 累計時間
FGC/FGCT Full GC 次數 / 累計時間
1
2
# 查看各記憶體區容量百分比
jstat -gcutil <pid> 1000

jmap — Heap 詳情與 Dump

1
2
3
4
5
6
7
8
# 查看 Heap 摘要(Java 11 以前)
jmap -heap <pid>

# Java 11+ 使用 jcmd 替代
jcmd <pid> GC.heap_info

# 產生 Heap Dump(用於後續分析)
jmap -dump:format=b,file=heap.hprof <pid>

Heap Dump 後可用 Eclipse Memory Analyzer (MAT)VisualVM 分析。

jcmd — 多功能診斷工具(推薦)

jcmd 是 Java 8+ 推薦的診斷工具,整合了多項功能:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 列出所有可用指令
jcmd <pid> help

# 查看 JVM 資訊
jcmd <pid> VM.info

# 查看原生記憶體(需啟動 JVM 時加 -XX:NativeMemoryTracking=summary)
jcmd <pid> VM.native_memory summary

# 觸發 GC
jcmd <pid> GC.run

# 產生 Heap Dump
jcmd <pid> GC.heap_dump filename=heap.hprof

# 查看 JVM 旗標設定
jcmd <pid> VM.flags

jinfo — 查看 JVM 參數

1
2
3
4
5
# 查看 JVM 所有屬性和設定
jinfo <pid>

# 查看特定參數
jinfo -flag MaxHeapSize <pid>

圖形化工具

VisualVM

JDK 內建的監控工具($JAVA_HOME/bin/jvisualvm),功能豐富:

  • 即時查看 Heap / CPU 使用率
  • 執行 Heap Dump 並分析物件
  • 支援 GC 即時圖表
  • 可連接遠端 JVM(JMX)

JConsole

較輕量的圖形化工具($JAVA_HOME/bin/jconsole):

1
2
3
4
# 啟動 JConsole
jconsole <pid>
# 或連接遠端
jconsole host:port

若要遠端連線,啟動應用時需加上:

1
2
3
4
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

常見記憶體問題排查

現象 可能原因 排查工具
Full GC 頻繁 Old Gen 空間不足 jstat -gcutil
Heap 持續增長 記憶體洩漏 jmap -dump + MAT
Metaspace OOM 動態 class 載入太多 jstat -gcmetacapacity
Thread Stack OOM 執行緒太多或遞迴過深 jstack <pid>

參考資料