JFR(Java Flight Recorder)是 JVM 内置的低开销运行时诊断工具,适合持续采集:
- CPU / 方法热点
- GC
- 线程阻塞、锁竞争
- 内存分配
- IO
- Socket
- JVM 异常
- Safepoint
1. 启动JVM时开启
1 2 3
| java \ -XX:StartFlightRecording=name=app,filename=/tmp/app.jfr,dumponexit=true \ -jar app.jar
|
生产环境更常用:
1 2 3
| java \ -XX:StartFlightRecording=name=app,settings=profile,maxage=1h,maxsize=1g,disk=true \ -jar app.jar
|
含义:
1 2 3
| maxage=1h 保留最近 1 小时 maxsize=1g 最大占用 1GB disk=true 持续写入磁盘
|
2. 对运行中的JVM开启 JFR
先查看 Java 进程:
启动采集:
1 2 3 4 5
| jcmd <PID> JFR.start \ name=recording \ settings=profile \ duration=5m \ filename=/tmp/app.jfr
|
5 分钟后自动生成:
也可以手动停止并导出:
1
| jcmd <PID> JFR.stop name=recording filename=/tmp/app.jfr
|
3. 持续Ring Buffer采集
适合生产环境:
1 2 3 4 5 6
| jcmd <PID> JFR.start \ name=continuous \ settings=default \ disk=true \ maxage=30m \ maxsize=500m
|
发生问题时再导出:
1 2 3
| jcmd <PID> JFR.dump \ name=continuous \ filename=/tmp/problem.jfr
|
核心思路:
1 2 3 4 5 6 7 8 9
| JVM 持续采集 ↓ 只保留最近 30 分钟 ↓ 出现 CPU / GC / 卡顿 ↓ 立即 dump ↓ 分析问题发生前后的 JVM 行为
|
4. 查看采集状态
5. 分析 JFR
推荐使用:
- Java Mission Control(JMC)
- IntelliJ IDEA Ultimate 的 JFR 支持
jfr 命令行
例如查看事件:
查看 GC:
1
| jfr print --events jdk.GarbageCollection app.jfr
|
6.生产环境推荐jfr采集
1 2 3 4 5 6
| jcmd <PID> JFR.start \ name=prod \ settings=default \ disk=true \ maxage=1h \ maxsize=1g
|
发生故障时:
1 2 3
| jcmd <PID> JFR.dump \ name=prod \ filename=/tmp/$(hostname)-$(date +%Y%m%d%H%M%S).jfr
|
本质
1 2 3 4 5 6 7 8 9 10 11 12 13
| 传统排障: 问题发生 ↓ 开始抓数据 ↓ 可能已经错过现场
JFR: 持续低开销记录 ↓ 问题发生 ↓ 导出过去一段时间的 JVM 历史
|
对于生产 JVM,通常建议 长期运行一个 default 配置的 Ring Buffer JFR,故障时 dump。这比临时启动 profiling 更容易捕获瞬时问题。