jstat -gc 1000 10 每秒采样10次,通过首尾YGC/FGC累计值相减得该时段实际GC次数;注意避免误用-jstat -gcutil、-jinfo及过短采样间隔,并结合-gccause和GC日志深入分析。

用 jstat -gc 每秒采样,看累计次数
jstat 是 OpenJDK 自带的轻量级监控工具,不依赖外部依赖,也不需要开启 JMX 或 GC 日志。统计一段时间内的 GC 次数,核心就是观察 YGC(Young GC 次数)和 FGC(Full GC 次数)字段的增量变化。
- 直接执行
jstat -gc <pid></pid>只输出当前快照,无法体现“一段时间内”的变化 - 正确做法是加时间间隔和次数参数:
jstat -gc <pid> 1000 10</pid>表示每 1000 毫秒查一次,共查 10 次
输出中每一行的YGC和FGC是自 JVM 启动以来的累计值,所以首尾相减就是该时间段内的实际发生次数
注意几个易错点:
- 别把
jstat -gcutil当成等价替代——它只显示百分比(如OU、YU),没有次数字段 - 如果进程刚启动不久,
FGC长期为 0,不代表没发生;某些 G1 场景下 Full GC 可能被退化为并发周期(G1 Evacuation Pause),此时FGC不增但YGCT或GCT明显跳变,需结合日志判断 - 采样间隔不能太短(如
100毫秒),否则可能因采样抖动导致YGC值来回跳变,误判为多次 GC
对比 jstat -gccause 看最近一次 GC 的触发原因
jstat -gccause <pid></pid> 会额外输出两列:LGCC(Last GC Cause)和 CGCC(Current GC Cause),比如 G1 Evacuation Pause 或 Allocation Failure。
这个命令本身不统计“次数”,但它能帮你确认:
- 某次 GC 是不是由内存分配失败直接触发(说明对象分配速率过高)
- 是否频繁出现
Metadata GC Threshold—— 那就不是堆问题,而是元空间快满了,得调-XX:MaxMetaspaceSize -
LGCC和CGCC长时间一致,说明 GC 原因稳定;如果频繁切换,可能有混合负载或配置冲突
别指望 jinfo 查 GC 次数
jinfo 只能读写 JVM 启动参数(如 -XX:+UseG1GC)或系统属性(jinfo -sysprops),它完全不接触运行时 GC 计数器。试图用 jinfo -flag 查 GC 次数会返回空或报错。
常见误操作:
-
jinfo -flag YGC <pid></pid>→ 报错:no such flag - 把
jinfo -flags输出里的-XX:+PrintGCDetails当成可统计开关 → 它只是控制日志输出,不提供计数接口
真要长期盯 GC 频率,得靠日志 + 外部解析
jstat 适合临时排查,但无法留存、聚合、告警。生产环境建议:
- 启动时加
-Xlog:gc*:file=gc.log:time,tags,level(JDK 10+)或-XX:+PrintGCDetails -XX:+PrintGCDateStamps(旧版) - 用
GCEasy上传日志,它会自动算出每分钟 GC 次数、平均停顿、吞吐量,并标出异常峰值 - 如果已有 ELK 或 Prometheus,可用
jvm_gc_collection_seconds_count这类 JMX 指标(需暴露-Dcom.sun.management.jmxremote)
GC 次数本身只是表象,YGC 每秒涨 5 次未必危险,但若每次后 EU(Eden 使用率)都清到接近 0,说明对象存活率极低,大概率是短生命周期对象暴增——这时候光看次数没用,得切到对象分配热点。


















