分配后是否共享 TLAB 分配的对象?

mak*_*XIE 1 jvm memory-management heap-memory

JVM Eden 空间中 TLAB 的设计让我感到困惑。我的问题是,如果对象是由 TLAB 中的一个线程分配的,那么它之后如何与其他线程共享?一个线程专有的TLAB区域会被重新组装,还是对象会被移出?

Hol*_*ger 5

TLAB 专门为一个线程进行的分配保留。它仍然是所有线程的相同共享地址空间内的内存。换句话说,它可以被所有线程访问

当然,一个对象只能被其他线程访问,如果您将对其的引用存储到共享变量中。由于在正常工作的 JVM 中,其他线程只能通过遍历这样的引用来访问内存,这意味着其他线程只能访问已由所有者分配给对象的 TLAB 的内存,并且至少需要最少的初始化在引用变为可观察之前,JMM 保证的工作已由所有者线程完成。

这种固有的正确性意味着其他线程不需要查看 TLAB 的实际分配状态,因此维护信息可以真正是线程本地的,例如保存在 CPU 寄存器中。

不管一个对象是否被多个线程共享,如果它在下一次垃圾收集之前存活(如果正在使用复制收集器),它只会从它的初始分配中移开。但是到发生这种情况时,对象被分配到的内存不再是 TLAB,因为使该内存成为 TLAB 的原因是它的使用方式。

在以前用作 TLAB 的内存区域被垃圾收集器清空后,它也可能作为新的 TLAB 重新分配给不同的线程(或用于不同的目的)。

  • 更准确地说,对象永远不会移出 TLAB。这更像是 TLAB 边界被移动了。TLAB 不是堆中的单独区域 - 它属于年轻代或 G1 区域或由所选 GC 定义的堆的任何部分。TLAB 只是一些指向堆的每线程指针。当线程分配一个新的TLAB(即设置指向新目标的指针)时,前一个TLAB会自动消失,变成常规共享堆。 (3认同)
  • 是的。TLAB 可以被视为由特定线程预分配的[共享]堆的连续区域。一旦线程预分配了新的 TLAB,或者发生了 GC(以先发生者为准),之前的预分配区域就会失去与该线程的连接。 (2认同)