目前,JDK 11 一共有136个 Event 采集配置。这里会比较详细的去看每一个Event,并说明基本应用,建议配置。如果 default.jfc 中没有打开或者需要修改的配置,会将配置文件代码发出来。
一共4个 Event,但是需要关心的就下面这两个
这些在 default.jfc 中默认打开
众所周知,TLAB (Thread Local Allocation Buffer)目的是为类进行内存快速分配。堆内存所有线程共享访问,所以在堆内存上面分配对象,就会锁定整个堆,这样效率太低。TLAB 是位于堆内存上面的一块内存区域,在为每个线程分配 TLAB 的时候才会锁定堆(G1 是CAS分配)。分配对象的时候,优先从线程的 TLAB 上分配,这样就不用和其他线程同步。当对象比较大的时候,例如对于 G1 来说, HeapRegionSize 配置大小的一半以上的对象就被认为是大对象,大对象的分配不会发生在 TLAB,不在 TLAB 发生的对象分配会涉及到线程同步。
这是比较笼统的看法,针对于 G1,这个算法更加复杂。为了能说明 JFR 相关事件的意义,这里继续深入一下关于 G1 TLAB 相关原理。
创建一个对象时:
涉及的 Event 以及默认配置:
这两个的采集,对性能影响比较大,不能长期跑。尤其是在启用堆栈收集后,影响就更大了。一般考虑动态打开。
一般应用:
配置打开示例:
true
true
true
true
事件 jmc 查看示例:
主要涉及三个 Event:
以 FileChannel
举例:
try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw");
FileChannel channel = reader.getChannel();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
int bufferSize = 1024;
ByteBuffer buff = ByteBuffer.allocate(bufferSize);
channel.read(buff); //产生 FileRead
channel.write(buff); // 产生 FileWrite
channel.force(true); // 强制不写入高速缓存,直接写入磁盘文件
channel.write(buff); // 产生 FileForce
}
这三个事件配置可以采集堆栈,设置采集时间阈值。在 default.jfc 中,这三个事件默认都是采集的,堆栈采集打开,并且阈值是20ms。如果你的应用只是打日志用到了文件,那个这个默认配置就很足够了。尤其是对于 Log4j2 的异步日志,这个阈值是够用的。如果你的应用需要高频操作文件,例如 RocketMQ 的 日志文件(基于 mmap)的,则这个阈值最好改成10ms,因为对文件写入读取速度要求更高。
主要涉及两个 Event:
我建议不用开启这两个 EVent 的采集,因为 Exception 我们可以通过日志分析, Error 一般框架都会有一些,一般与为我们的业务无关。