Java JFR 民间指南 - 事件详解 - jdk.ObjectAllocationInNewTLAB (3)

在发生 TLAB 重分配的时候,会立刻生成这个事件并上报,对应源码:
allocTracer.cpp

//在每次发生 TLAB 重分配的时候,调用这个方法上报 void AllocTracer::send_allocation_in_new_tlab(Klass* klass, HeapWord* obj, size_t tlab_size, size_t alloc_size, Thread* thread) { JFR_ONLY(JfrAllocationTracer tracer(obj, alloc_size, thread);) //立刻生成 jdk.ObjectAllocationInNewTLAB 这个事件 EventObjectAllocationInNewTLAB event; if (event.should_commit()) { event.set_objectClass(klass); event.set_allocationSize(alloc_size); event.set_tlabSize(tlab_size); event.commit(); } const int64_t allocated_bytes = load_allocated_bytes(thread); if (allocated_bytes == 0) { return; } //采样 jdk.ObjectAllocationSample 事件 send_allocation_sample(klass, allocated_bytes); }

通过源码分析我们可以知道,如果开启这个事件,那么只要发生 TLAB 重分配,就会生成并采集一个 jdk.ObjectAllocationInNewTLAB 事件。

为何一般不在先生持续开启这个事件

这个事件配置项比较少,只要开启,就会发生一个 TLAB 重分配,就生成并采集一个 jdk.ObjectAllocationInNewTLAB 事件。对于大型项目来说,分析这个事件,如果没有堆栈,会很难定位。并且,并不是所有的 TLAB 重分配都是性能瓶颈,但是也无法简单的动态采集定位。如果需要动态开启采集,需要我们写额外的代码实现。如果开启堆栈采集,那么只要发生比较大量的 jdk.ObjectAllocationInNewTLAB 事件,就会成为性能瓶颈,因为堆栈采集是很耗费性能的。目前大部分的 Java 线上应用,尤其是微服务应用,都使用了各种框架,堆栈非常深,可能达到几百,如果涉及响应式编程,这个堆栈就更深了。JFR 考虑到这一点,默认采集堆栈深度最多是 64,即使是这样,也还是比较耗性能的。并且,在 Java 11 之后,JDK 一直在优化获取堆栈的速度,例如堆栈方法字符串放入缓冲池,优化缓冲池过期策略与 GC 策略等等,但是目前性能损耗还是不能忽视。

如果你不想开发额外代码,还想线上持续监控的话,建议使用 Java 16 引入的 jdk.ObjectAllocationSample

总结

jdk.ObjectAllocationInNewTLAB 监控 TLAB 重分配事件,如果开启,只要发生 TLAB 重分配,就会生成并采集一个 jdk.ObjectAllocationInNewTLAB 事件。

开启采集,并打开堆栈采集的话,会非常消耗性能。

如果你不想开发额外代码,还想线上持续监控的话,建议使用 Java 16 引入的 jdk.ObjectAllocationSample

微信搜索“我的编程喵”关注公众号,加作者微信,每日一刷,轻松提升技术,斩获各种offer:

image

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdydp.html