浅谈本地线程分配缓冲——TLAB

前言

本篇主要作为上一篇博客(浅谈Java堆中对象的创建、布局和访问过程)进一步介绍TLAB(Thread Local Allocation Buffer)。

本地线程分配缓冲——TLAB

TLAB是虚拟机在堆内存的划分出来的一块专用空间,是线程专属的。在TLAB启动的情况下,在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。

ps:这里说线程独享的堆内存,只是在“内存分配”这个动作上是线程独享的,至于在读取、垃圾回收等动作上都是线程共享的。即是指其他线程可以在这个区域读取、操作数据,但是无法在这个区域中分配内存。

TLAB 生命周期

在分代收集的垃圾回收器中,TLAB是在eden区分配的。TLAB 是从堆上 Eden 区的分配的一块线程本地私有内存。线程初始化的时候,如果 JVM 启用了 TLAB(默认是启用的, 可以通过 -XX:-UseTLAB 关闭),则会创建并初始化 TLAB。同时,在 GC 扫描对象发生之后,线程第一次尝试分配对象的时候,也会创建并初始化 TLAB

在 TLAB 已经满了或者接近于满了的时候,TLAB 可能会被释放回 Eden。GC 扫描对象发生时,TLAB 会被释放回 Eden。TLAB 的生命周期期望只存在于一个 GC 扫描周期内。在 JVM 中,一个 GC 扫描周期,就是一个epoch。那么,可以知道,TLAB 内分配内存一定是线性分配的。

TLAB的大小

TLAB的初始大小可由参数-XX:TLABSize指定,若指定了TLAB的值,TLAB初始大小就是TLABSize。否则,TLAB大小为分配线程的平均值。

源码地址:https://github.com/openjdk/jdk/blob/master/src/hotspot/share/gc/shared/threadLocalAllocBuffer.cpp

TLAB 的大小的最小值:通过MinTLABSize指定
TLAB 的大小的最大值:不同GC中有不同的最大值。例如G1 GC中,TLAB的最大值为大对象的大小,即是Region的一半ZGC中的最大值为1/8的Region,在大部分情况下 Shenandoah GC 也是每个 Region 大小的 8 分之一。对于其他的 GC,则是 int 数组的最大大小

在这里插入图片描述
TLAB空间大小的动态调整
默认情况下:

-XX:ResizeTLAB

resize开关是默认开启的,JVM可以对TLAB空间大小进行调整。

对象的慢分配
当TLAB内存充足时,分配新对象的方式称为快分配。当TLAB内存不足,分配新对象的方式称为“慢分配”。慢分配有两种处理方式:

1、当TLAB剩余内存空间小于TLAB最大浪费空间时,丢弃当前 TLAB 回归 Eden,线程获取新的 TLAB 分配对象。
2、当TLAB剩余内存空间大于TLAB最大浪费空间时,对象直接在Eden区分配内存。

TLAB最大浪费空间
最大浪费空间是一个动态值,TLAB最大浪费空间初始值=TLAB大小/TLABRefillWasteFraction。TLABRefillWasteFraction默认为64,所以TLAB最大浪费空间初始值为TLAB大小的1/64。伴随着每次慢分配,这个TLAB最大浪费空间会每次递增 TLABWasteIncrement 大小的空间。

总结

TLAB流程总结:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参数总结

参数名称参数作用
UseTLAB是否启用 TLAB,默认是启用的。
ResizeTLABTLAB 是否是自适应可变的,默认为是
TLABSize初始 TLAB 大小,单位是字节 。默认为0,0 就是不主动设置 TLAB 初始大小,而是通过 JVM 自己计算每一个线程的初始大小。例如:-XX:TLABSize=65536
MinTLABSize最小 TLAB 大小。单位是字节,默认2048。例如-XX:MinTLABSize=4096
TLABRefillWasteFraction在一次 TLAB 再填充(refill)发生的时候,最大的 TLAB 浪费。默认为64,和TLAB最大浪费空间有关 。TLAB最大浪费空间= TLAB大小/TLABRefillWasteFraction
TLABWasteIncrementTLAB 慢分配时允许的 TLAB 浪费增量

参考资料

通过 JFR 与日志深入探索 JVM - TLAB 原理详解——很棒的一篇文章,从源码讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值