JVM如何利用TLAB机制,通过线程私有分配区缓解堆内存分配中的锁竞争问题?
- 内容介绍
- 相关推荐
本文共计816个文字,预计阅读时间需要4分钟。
JVM通过为每个线程在Eden区划分一块私有内存(即TLAB),使对象分配从争抢同一块内存变为各有各的缓冲区,从而减少锁的开销。核心不在于加锁的粒度,而在于大量分配操作无需锁。
TLAB 是 Eden 区内的线程专属小块空间
TLAB 并非独立于堆外的新内存区域,而是 JVM 在新生代 Eden 区中为每个线程动态划出的一段连续内存。它属于堆的一部分,但逻辑上只对该线程可见和可写。线程启动时,JVM 自动为其分配一个初始大小的 TLAB;后续对象分配优先落在其中。
- 默认启用,无需手动开启(-XX:+UseTLAB 是默认行为)
- 大小受控:初始约占 Eden 的 1%,可通过 -XX:TLABWasteTargetPercent 调整目标占比
- 仅限小对象:超过 TLAB 剩余空间或超过预设阈值(如 -XX:TLABSize 或 JVM 内部启发式上限)的对象,直接绕过 TLAB
分配过程完全无锁:靠指针递增实现原子性
线程在自己的 TLAB 中分配对象,本质是移动一个本地指针(bump-the-pointer)。只要指针更新不越界,整个过程就是纯 CPU 寄存器操作,无需任何同步机制。
本文共计816个文字,预计阅读时间需要4分钟。
JVM通过为每个线程在Eden区划分一块私有内存(即TLAB),使对象分配从争抢同一块内存变为各有各的缓冲区,从而减少锁的开销。核心不在于加锁的粒度,而在于大量分配操作无需锁。
TLAB 是 Eden 区内的线程专属小块空间
TLAB 并非独立于堆外的新内存区域,而是 JVM 在新生代 Eden 区中为每个线程动态划出的一段连续内存。它属于堆的一部分,但逻辑上只对该线程可见和可写。线程启动时,JVM 自动为其分配一个初始大小的 TLAB;后续对象分配优先落在其中。
- 默认启用,无需手动开启(-XX:+UseTLAB 是默认行为)
- 大小受控:初始约占 Eden 的 1%,可通过 -XX:TLABWasteTargetPercent 调整目标占比
- 仅限小对象:超过 TLAB 剩余空间或超过预设阈值(如 -XX:TLABSize 或 JVM 内部启发式上限)的对象,直接绕过 TLAB
分配过程完全无锁:靠指针递增实现原子性
线程在自己的 TLAB 中分配对象,本质是移动一个本地指针(bump-the-pointer)。只要指针更新不越界,整个过程就是纯 CPU 寄存器操作,无需任何同步机制。

