OpenJDK 1.8中需同时配置-Xloggc、-XX:+UseGCLogFileRotation、-XX:NumberOfGCLogFiles和-XX:GCLogFileSize四参数才能实现GC日志轮转,缺一则失效;路径权限、inode耗尽及归档遗漏亦需防范。

OpenJDK 1.8 中必须配齐这四个参数才能轮转
只加 -Xloggc:/path/gc.log 不会轮转,日志会无限追加直到磁盘写满。真正起作用的是配套的三个开关参数,缺一不可:
-
-XX:+UseGCLogFileRotation:必须启用,否则轮转逻辑根本不触发 -
-XX:NumberOfGCLogFiles=5:保留最多 5 个文件(含当前gc.log),超出后最老的被覆盖 -
-XX:GCLogFileSize=30M:单个文件达到 30MB 就切新文件,不是按时间切
另外两个常被忽略但影响可读性的参数也建议加上:-XX:+PrintGCDetails 和 -XX:+PrintGCDateStamps,否则日志里没有时间戳、没有分代细节,基本没法分析。
路径和权限问题比参数更容易导致日志静默丢失
常见现象是“明明配了日志参数,却找不到 gc.log”。根本原因往往不是 JVM 配置错,而是路径或权限问题:
- 目录不存在 → JVM 不报错,直接放弃写日志(
/var/log/myapp/必须提前mkdir -p并chown给运行用户) - 路径用了相对路径(如
-Xloggc:gc.log)→ 日志生成在启动时的当前工作目录,而该目录可能随 systemd 或容器启动方式变化,极难定位 - 多个 Java 进程共用同一路径(如都写
/var/log/app/gc.log)→ 文件被并发覆盖或损坏,尤其在容器重启频繁时
推荐写法:-Xloggc:/var/log/myapp/gc-${APP_NAME}-${PID}.log,配合 UseGCLogFileRotation 后,实际生成的是 gc-myapp-1234.log、gc-myapp-1234.log.1 等。
OpenJDK 17+ 用户注意:-Xloggc 已废弃,改用 -Xlog
如果你用的是 OpenJDK 17 或更高版本(比如 21 LTS),-Xloggc 和所有 -XX:* 日志相关参数已彻底移除。必须改用统一的日志系统 -Xlog:
- 等效写法:
-Xlog:gc*:file=/var/log/myapp/gc.log:time,uptime,level,tags:filecount=5,filesize=30M - 其中
filecount和filesize对应旧版的NumberOfGCLogFiles和GCLogFileSize -
gc*表示开启所有 GC 相关日志,如需精简可写成gc+heap=debug等
不兼容提示:在 JDK 17+ 上继续用 -XX:+UseGCLogFileRotation 会直接报错 Unrecognized VM option,JVM 启动失败。
轮转不是“开了就完事”,要防 inode 耗尽和归档遗漏
轮转本身解决的是单文件膨胀问题,但容易忽略两个生产环境高频故障点:
- Linux 的 ext4 文件系统对小文件敏感——即使总磁盘空间充足,
df -i显示 inode 使用率 100% 时,轮转会失败(无法创建新文件) - 轮转只管生成和覆盖,不管压缩和归档。历史
gc.log.9被覆盖前,若没用logrotate或类似工具做gzip+rotate,磁盘可能在几小时内被撑爆
建议在日志目录所在分区上定期检查 df -i,并在部署脚本中加入 logrotate 配置,例如为 /var/log/myapp/gc-*.log 设置 weekly rotate + compress。


















