jstat是jdk自带的轻量级命令行工具,可实时监控java进程gc状态;需先用jps -l获取pid,再通过-gcutil观察内存使用率趋势、-gc查看gc次数与耗时、-gccause定位最近gc原因,结合间隔采样(如2000ms)和表头刷新(-h3)持续跟踪eden/old/metaspace变化,以识别内存泄漏、gc瓶颈等异常。

直接用 jstat 就能快速查看 Java 进程的 GC 状态,不需要装额外工具,也不影响应用运行。关键不是只看一次数字,而是观察变化趋势——比如 Eden 区是否反复打满、老年代是否缓慢上涨、Full GC 是否突然变多。
先确认目标进程 PID
没 PID 就没法监控,得先找:
- 运行 jps -l,列出所有 Java 进程及其主类(Spring Boot 应用通常显示为 JarLauncher)
- 如果进程太多难分辨,加 -m 看启动参数,或 -v 看 JVM 参数(比如能一眼看到
-Xmx2g) - 注意:极少数环境禁用了性能数据采集(
-XX:-UsePerfData),jstat 会报错;默认是开启的,一般不用动
常用 jstat 命令与核心指标
选对选项才能抓到问题信号:
-
jstat -gcutil
:看各区域使用率(百分比)。重点关注:
• E(Eden)长期 >90% → 新生代可能太小或对象分配过快
• O(老年代)持续上升 + FGC同步增加 → 可能有内存泄漏或对象晋升异常
• M(元空间)持续增长 → 检查反射、动态代理、字节码生成框架(如 MyBatis、CGLIB) -
jstat -gc
:看原始数值。重点盯:
• YGC(年轻代 GC 次数)和 YGCT(总耗时)→ 单次 YGCT 超 100ms 或每秒 YGC >5 次,说明新生代压力大
• FGC(Full GC 次数)和 FGCT(单次耗时)→ FGC >0 且 FGCT 超 1 秒,必须立即查 -
jstat -gccause
:比 -gcutil 多一列 LGCC(Last GC Cause),告诉你最近一次 GC 是因为什么触发的,比如 Allocation Failure(正常)还是Metadata GC Threshold(元空间快满了)
带节奏地持续观察
单次输出意义不大,要看出变化才有价值:
- 加时间间隔和次数:例如 jstat -gcutil 12345 2000 5 表示每 2 秒输出一次,共 5 次
- 加 -t 显示进程已运行秒数,方便算 GC 时间占比:
若GCT / 运行时间 > 20%,GC 开始拖慢吞吐;超过 50%,系统基本不可用 - 加 -h 3 每 3 行输出一次表头,避免滚动后看错列
怎么看才算“出问题”
数字本身不说话,变化节奏才暴露真相:
- 老年代(O 列)缓慢但稳定上升,FGC 隔几分钟就来一次 → 很可能是对象本该被回收却一直被引用(如静态 Map 缓存未清理)
- Eden 区(E 列)每次 GC 后回收不干净,Survivor(S0/S1)使用率居高不下 → SurvivorRatio 设置不合理,或大量中龄对象卡在 Survivor 区没晋升也没死亡
- YGC 耗时(YGCT)明显拉长,比如从平均 25ms 跳到 80ms+ → 新生代可能碎片化严重,或者突发大批短生命周期对象集中分配
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











