
本文详解如何为长期运行的 Java 应用配置 JFR(Flight Recorder)的自动轮转机制,通过 maxage 和 maxsize 参数实现按时间或大小切分录制文件,并避免意外启动默认记录。
本文详解如何为长期运行的 java 应用配置 jfr(flight recorder)的自动轮转机制,通过 `maxage` 和 `maxsize` 参数实现按时间或大小切分录制文件,并避免意外启动默认记录。
Java Flight Recorder(JFR)是 JVM 内置的高性能诊断与监控工具,适用于生产环境的低开销事件采集。但对持续运行数天甚至数周的服务(如每周运行 6 天的后台应用),若仅依赖 dumponexit=true,将导致单个 .jfr 文件累积海量数据——不仅体积庞大、分析困难,还存在内存与磁盘风险。幸运的是,JFR 原生支持基于时间或大小的自动轮转(rotation),无需外部脚本干预。
✅ 正确启用轮转的关键参数
轮转行为由 FlightRecorderOptions 中的 maxage 或 maxsize 触发,二者可单独使用,不可同时指定(JVM 启动时会报错)。轮转发生时,当前录制文件自动关闭并写入磁盘,新文件随即创建,且文件名中自动追加时间戳(格式为 yyyyMMdd_HHmmss),确保唯一性与可追溯性。
▸ 按时间轮转:maxage
适用于需固定周期归档(如每日一录)的场景:
-XX:FlightRecorderOptions=\ defaultrecording=false,\ dumponexit=true,\ dumponexitpath=$APP_HOME/logs/$APP_NAME.jfr,\ maxage=24h
⚠️ 注意:dumponexitpath 中的 $APP_NAME.jfr 是模板路径,实际生成文件名为类似 myapp_20241005_143022.jfr。maxage=24h 表示每 24 小时触发一次轮转(非严格准时,而是“最近一次轮转后超过 24 小时的首个事件触发”)。
立即学习“Java免费学习笔记(深入)”;
▸ 按大小轮转:maxsize
适用于事件密度高、需控制单文件体积的场景(如防止单文件超 1GB):
-XX:FlightRecorderOptions=\ defaultrecording=false,\ dumponexit=true,\ dumponexitpath=$APP_HOME/logs/$APP_NAME.jfr,\ maxsize=1g
? maxsize 支持单位:k/K、m/M、g/G(不区分大小写)。当当前录制文件达到阈值时,立即切换至新文件。
⚠️ 关键注意事项
务必设置 defaultrecording=false
如原配置中 defaultrecording=true,JVM 启动即自动开启默认录制,而轮转逻辑仅作用于 显式启动的录制(如通过 JMX 或 jcmd)。设为 false 可避免冗余记录,轮转功能才能生效——这是多数用户忽略却至关重要的一步。dumponexit 仍有效,但仅作用于最后一次录制
轮转后,dumponexit=true 仅保证 JVM 退出时将当前活跃的录制文件写入磁盘,不会合并或覆盖历史轮转文件。时间戳命名是自动行为,无需手动拼接 $NOW
原配置中 $APP_NAME_$NOW.jfr 的手动时间变量在轮转场景下应移除,改用静态基础名(如 $APP_NAME.jfr),由 JVM 自动注入时间戳,否则轮转将失败或生成非法文件名。验证轮转是否生效
启动后检查日志目录,观察是否出现多个带时间戳的 .jfr 文件;也可通过 jcmd <pid> VM.native_memory summary 或 JMC(Java Mission Control)连接确认当前录制状态。
✅ 推荐完整启动参数示例
JFR_OPTS="-XX:+UnlockCommercialFeatures \
-XX:+UnlockDiagnosticVMOptions \
-Djava.net.IPv4Stack=true \
-XX:+FlightRecorder \
-XX:FlightRecorderOptions=\
stackdepth=128,\
defaultrecording=false,\
dumponexit=true,\
dumponexitpath=$APP_HOME/logs/myapp.jfr,\
maxage=12h"此配置启用深度调用栈采集,每 12 小时轮转一次,兼顾分析精度与磁盘可控性。
掌握 JFR 轮转机制,不仅能规避“单文件爆炸”风险,更能构建可持续的生产级性能观测体系——让诊断数据真正成为运维与优化的可靠依据,而非负担。










