JVM开启JFR采集

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
jps -l

启动采集:

1
2
3
4
5
jcmd <PID> JFR.start \
name=recording \
settings=profile \
duration=5m \
filename=/tmp/app.jfr

5 分钟后自动生成:

1
/tmp/app.jfr

也可以手动停止并导出:

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. 查看采集状态

1
jcmd <PID> JFR.check

5. 分析 JFR

推荐使用:

  • Java Mission Control(JMC)
  • IntelliJ IDEA Ultimate 的 JFR 支持
  • jfr 命令行

例如查看事件:

1
jfr print app.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 更容易捕获瞬时问题。