From 2fe0c9d963de74931f2a882019b09352beb68267 Mon Sep 17 00:00:00 2001 From: 8ga Date: Thu, 13 Mar 2025 15:40:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20JFR/3=5FEvent=E9=87=87?= =?UTF-8?q?=E9=9B=86=E8=AF=A6=E7=BB=86=E9=85=8D=E7=BD=AE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- JFR/3_Event采集详细配置.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/JFR/3_Event采集详细配置.md b/JFR/3_Event采集详细配置.md index 25a3b32..48cc867 100644 --- a/JFR/3_Event采集详细配置.md +++ b/JFR/3_Event采集详细配置.md @@ -12,3 +12,16 @@ ##### 1、Thread Local Allocation Buffer(TLAB) +TLAB 目的是为了快速分配内存。堆内存是线程共享的,所以在堆内存直接分配对象,就会锁定整个堆,这样效率太低。TLAB 是位于堆内存的一块内存区域,在为每个线程分配 TLAB 的时候才会锁定堆(G1 是 CAS 分配)。这样一来,每个线程在分配对象的时候,优先从 TLAB 上分配。大对象的分配不会发生在 TLAB,将会涉及到线程同步。这是比较笼统的看法,G1 的情况更加复杂。为了能说明 JFR 相关事件的意义,这里继续深入一下关于 G1 TLAB 相关原理。创建一个对象时: + +- 首先尝试从线程现有的TLAB空间分配内存 +- 如果剩余空间不足,查看是否能分配一个新的TLAB,再分配内存给对象。每个线程的 TLAB 大小是随着线程运行不断变化的。TLAB 的内部,每个线程维护着一个*refill_waste*的变量,这个变量的值,决定是否能分配一个新的TLAB。 +- 当 TLAB 剩余空间不足时,查看当前 TLAB 的剩余大小 + + 如果小于*refill_waste*则需要分配一个新的TLAB,这时候,JFR 会产生一条*ObjectAllocationInNewTLAB*记录 + + 否则认为这个 TLAB 还不算满,当前这个对象将直接走堆上内存分配,这时会产生一条*ObjectAllocationOutsideTLAB*记录 + +*ObjectAllocationInNewTLAB*在 default.jfc 中默认关闭,可以通过向导配置*memory-profiling*调为*memory-profiling-enabled-medium*打开。也可以用高级配置这个 Event 是否采集,以及堆栈是否采集。采集内容包括:时间、线程、本次需要分配内存大小、对象类型、当前 TLAB 大小。 + +*ObjectAllocationOutsideTLAB*在 default.jfc 中也是默认关闭的,可以通过向导配置*memory-profiling*调为*memory-profiling-enabled-medium*打开。也可以用高级配置这个 Event 是否采集,以及堆栈是否采集。采集内容包括:时间、线程、本次需要分配内存大小、对象类型。 + +**这两个的采集,对性能影响比较大,不能长期跑。尤其是在启用堆栈收集后,影响就更大了。一般考虑动态打开。** \ No newline at end of file