如何识别JFR的Instant Event、Duration Event、Sample Event三类事件类型
JFR三类事件核心定义&准确区分方法
不要通过JFR配置项的参数形式判断事件类型,该方式存在明显误差,需通过事件底层元数据和实现逻辑判断,具体规则如下:
三类JFR事件的核心差异
- Instant Event(即时事件):触发即记录,无持续时间属性,只要开启事件就默认记录全量数据,无内置采样逻辑,比如线程启动事件
jdk.ThreadStart、类加载事件jdk.ClassLoad都属于该类。 - Duration Event(持续事件):记录有时间跨度的操作,自带
startTime和duration属性,支持配置阈值,仅当操作耗时超过阈值时才会记录,阈值设为0时可记录全量该类事件,比如GC暂停事件jdk.GCPhasePause、文件读取事件jdk.FileRead属于该类。 - Sample Event(采样事件):底层基于采样逻辑实现,无论如何配置都只会记录符合采样条件的部分事件,无法生成全量记录,核心元数据会标注
@Sampled注解,你提到的jdk.ObjectAllocationInNewTLAB就是典型的采样事件,采样频率由JVM的TLAB分配采样参数控制,即使开启事件也只会记录采样命中的分配请求。
准确区分事件类型的可落地方法
方法1:通过jfr命令查询事件元数据
用JDK自带的jfr工具直接查询指定事件的元数据,是最准确的判断方式,命令格式:jfr metadata --events <事件名>
例如查询jdk.ObjectAllocationInNewTLAB的元数据:jfr metadata --events jdk.ObjectAllocationInNewTLAB
输出结果的判定规则:
- 包含
@jdk.jfr.Sampled注解:采样事件 - 无
@Sampled注解但包含duration属性:持续事件 - 既无
@Sampled注解也无duration属性:即时事件
方法2:通过JMC的事件类型浏览器查看
打开JDK Mission Control,进入事件类型浏览器,找到对应事件:
- 事件属性中「采样」字段值为是:采样事件
- 事件属性中存在「阈值」配置项:持续事件
- 以上两个特征都不存在:即时事件
方法3:查询OpenJDK的JFR事件定义源码
所有JDK内置事件的定义都在jdk.jfr.internal.event包下,每个事件类的注解直接标识了类型:
- 类上加了
@Sampled注解:采样事件 - 类继承了
jdk.jfr.Event且包含duration字段定义:持续事件 - 无上述特征的即时触发事件:即时事件
获取全量非采样数据的注意事项
- 采样事件无论如何配置都无法拿到全量数据,如果需要全量分配这类数据,可使用其他工具替代,或者修改JVM参数把采样率调到最高(会带来极高的性能开销,不建议生产环境使用)
- 持续事件要拿到全量数据,仅需把对应事件的阈值设置为
0ns即可,注意高频持续事件开全量会导致JFR文件体积暴涨,性能开销升高 - 即时事件只要开启就会生成全量记录,不需要额外配置
内容的提问来源于stack exchange,提问作者llllb
相关产品推荐
相关产品推荐

