如何使用JDK自带的jstat工具监测JVM内存使用情况?

jstat 是 JDK 自带的轻量级命令行工具,用于实时监控 JVM 的内存使用、垃圾回收(GC)、类加载等统计信息。它无需额外配置,通过简单命令即可快速获取 JVM 运行状态,适合在开发、测试或生产环境中做基础监测。

一、jstat 基本用法

命令格式

bash

复制代码
jstat [选项] <pid> [间隔时间(毫秒)] [查询次数]
  • 选项:指定监控的指标(如内存、GC、类加载等,必填)。
  • pid :Java 进程 ID(必填,通过jps命令获取)。
  • 间隔时间:每次输出的时间间隔(毫秒,可选,默认立即输出一次)。
  • 查询次数 :输出的总次数(可选,默认无限次,需手动Ctrl+C终止)。

二、获取 Java 进程 PID

使用jps(JDK 自带)查看当前运行的 Java 进程 ID:

bash

复制代码
jps -l  # 显示进程PID和完整主类名

示例输出:

复制代码
12345 org.springframework.boot.loader.JarLauncher  # PID为12345的Spring Boot应用
67890 sun.tools.jps.Jps

记住需要监测的进程 PID(如12345)。

三、常用监控选项及示例

jstat提供多个选项,核心关注内存和 GC 相关指标,以下是最常用的几个:

1. 监控 GC 整体情况:-gc

作用 :显示 JVM 堆内存各区域(Eden、Survivor、Old、Metaspace)的容量、使用量,以及 GC 次数和时间。
命令示例

复制代码
jstat -gc 12345 1000 5  # 监测PID=12345,每1000ms输出1次,共5次

输出字段解释

字段 含义
S0C Survivor 0 区总容量(KB)
S1C Survivor 1 区总容量(KB)
S0U Survivor 0 区已使用容量(KB)
S1U Survivor 1 区已使用容量(KB)
EC Eden 区总容量(KB)
EU Eden 区已使用容量(KB)
OC Old 区(老年代)总容量(KB)
OU Old 区已使用容量(KB)
MC Metaspace(元空间)总容量(KB)
MU Metaspace 已使用容量(KB)
CCSC 压缩类空间总容量(KB,JDK8+)
CCSU 压缩类空间已使用容量(KB,JDK8+)
YGC Young GC(新生代 GC)总次数
YGCT Young GC 总耗时(秒)
FGC Full GC(全局 GC)总次数
FGCT Full GC 总耗时(秒)
GCT 所有 GC 总耗时(秒,=YGCT+FGCT)

解读重点

  • 观察EU(Eden 区使用量)是否快速增长,若频繁达到EC(总容量),说明 Young GC 频繁。
  • OU(Old 区使用量)持续增长并接近OC(总容量),可能导致 Full GC 频繁,需警惕内存泄漏。
2. 监控 GC 使用率:-gcutil

作用 :以百分比形式显示堆内存各区域的使用率,以及 GC 次数和时间(比-gc更简洁)。
命令示例

复制代码
jstat -gcutil 12345 2000  # 每2000ms输出1次,无限次(按Ctrl+C停止)

输出字段解释

字段 含义
S0 Survivor 0 区使用率(%)
S1 Survivor 1 区使用率(%)
E Eden 区使用率(%)
O Old 区使用率(%)
M Metaspace 使用率(%)
CCS 压缩类空间使用率(%)
YGC Young GC 总次数
YGCT Young GC 总耗时(秒)
FGC Full GC 总次数
FGCT Full GC 总耗时(秒)
GCT 所有 GC 总耗时(秒)

解读重点

  • E(Eden 区使用率)若频繁接近 100%,说明 Young GC 触发频繁,可能需要调整新生代大小(如-Xmn参数)。
  • O(Old 区使用率)若持续升高,需检查是否有大对象直接进入老年代,或存在内存泄漏(对象未被回收)。
  • FGC(Full GC 次数)若频繁增加(如每分钟多次),可能导致应用卡顿(Full GC 会暂停用户线程),需紧急排查。
3. 监控内存容量变化:-gccapacity

作用 :显示堆内存各区域(新生代、老年代、元空间)的最大容量、当前容量等信息,适合分析内存分配是否合理。
命令示例

复制代码
jstat -gccapacity 12345

输出核心字段

字段 含义
NGCMN 新生代最小容量(KB)
NGCMX 新生代最大容量(KB)
NGC 新生代当前容量(KB)
OGCMN 老年代最小容量(KB)
OGCMX 老年代最大容量(KB)
OGC 老年代当前容量(KB)
MCMN Metaspace 最小容量(KB)
MCMX Metaspace 最大容量(KB)
MC Metaspace 当前容量(KB)
4. 监控类加载情况:-class

作用 :显示类加载、卸载的数量及耗时,辅助判断类加载是否异常(如频繁加载卸载)。
命令示例

复制代码
jstat -class 12345

输出字段

  • Loaded:已加载的类数量
  • Bytes:已加载类的总大小(KB)
  • Unloaded:已卸载的类数量
  • Bytes:已卸载类的总大小(KB)
  • Time:类加载和卸载的总耗时(秒)

四、实际使用场景

  1. 快速判断 GC 是否正常

    jstat -gcutil <pid> 1000实时观察,若FGC频繁(如 1 分钟内多次)且O(老年代使用率)持续接近 100%,可能存在内存泄漏。

  2. 分析内存分配是否合理

    -gccapacity查看新生代 / 老年代的最大容量与当前容量,若新生代频繁满(E使用率骤升),可尝试调大新生代(如-Xmn512m)。

  3. 评估 GC 耗时对性能的影响

    YGCT(Young GC 耗时)单次超过 100ms,或FGCT(Full GC 耗时)超过 1 秒,可能导致应用响应延迟(需结合业务容忍度判断)。

五、注意事项

  • jstat仅能监控本地 JVM 进程;远程监控需配置 JMX(Dcom.sun.management.jmxremote)。
  • 若提示 "命令未找到",检查JAVA_HOME是否配置正确,jstat位于$JAVA_HOME/bin目录下。
  • 生产环境中,建议结合 GC 日志(通过-Xlog:gc*:file=gc.log开启)做更详细分析,jstat适合快速实时观测。

通过jstat的轻量特性,可以在不影响应用运行的前提下,快速掌握 JVM 内存和 GC 的基本状态,为进一步优化或排查问题提供依据。