最有效的方式是通过JVM启动参数开启GC日志并结合停顿时间、回收频率、内存变化趋势三项指标分析;JDK10+用-Xlog:gc*:file=gc.log:time,tags,level,旧版本用-XX:+PrintGCDetails等组合,并必须配置-XX:+UseGCLogFileRotation等滚动参数防磁盘溢出。

直接在 JVM 启动时加参数就能开启 GC 日志,但要保证它能长期稳定保存、不占满磁盘、方便排查问题,就得搭配轮转和路径规范。
基础开启方式(启动时配置)
根据 JDK 版本选择对应参数:
-
JDK 10 及以上:用统一日志框架,推荐
-Xlog:gc*:file=gc.log:time,tags,level
支持精细控制输出内容、时间格式和日志级别。 -
JDK 8/9:传统参数组合
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log
必须同时启用详细信息和时间戳,否则日志缺少关键上下文。
必须加的日志滚动参数(防磁盘打爆)
只写 -Xloggc:gc.log 会导致日志无限追加,单文件越来越大,最终无法打开或写满磁盘。生产环境务必加上轮转:
- -XX:+UseGCLogFileRotation:开启轮转功能(不加这个,其他轮转参数无效)
- -XX:NumberOfGCLogFiles=5:最多保留 5 个历史文件(建议 5~10)
- -XX:GCLogFileSize=10M:单个日志达 10MB 就滚动(避免单文件过大难分析)
路径与权限注意事项
日志写不进去,往往不是参数错,而是路径出问题:
- 目标目录必须存在,且 JVM 进程有写权限;不存在目录时,JVM 不报错,日志直接静默丢失
- 多实例部署时,避免共用同一日志路径,否则可能覆盖或并发写坏;推荐加入应用名与 PID:
-Xloggc:/var/log/myapp/gc-${APP_NAME}-${PID}.log - 留意磁盘空间和 inodes 是否耗尽——轮转失败常因这两项资源不足
运行时动态开启(不重启应用)
线上服务不能停机?JDK 7u40 起支持通过 JMX 或 jcmd 实时开关 GC 日志:
- 查进程 ID:
jps -l - 动态开启并输出到文件:
jcmdVM.log output=gc+heap*=debug file=gc_runtime.log - 关闭日志:
jcmdVM.log disable - 该方式适用于紧急诊断,但不替代启动时的长期配置










