什么是TLAB(线程本地分配缓冲区)?

47

我找不到一个全面的资源来清晰地解释这个概念。我的理解是,线程在eden区中被分配一些内存块以分配新对象。竞争的线程最终会在eden区中找到一些相邻的内存块。如果第一个线程在其TLAB中用完了所有的空闲区域会发生什么?它会请求一个新的eden区块吗?


关于您上一个问题,我猜测线程会被分配一个新的TLAB。考虑分配TLAB而不是小内存块,这是一种简单的优化方法,使频繁工作线程本地化而不需要锁定。 - maaartinus
1个回答

62
TLAB的想法是减少线程之间同步的需求。使用TLAB,可以减少这种需求,因为任何线程都有一个可以使用的区域,并期望它是唯一使用该区域的线程。假设一个TLAB可以容纳100个对象,当分配第101个对象时,线程只需要获取锁来声明更多内存即可。没有TLAB,对于每个对象都需要这样做。缺点当然是可能会浪费空间。
大型对象通常在TLAB之外分配,因为它们取消了减少同步内存分配频率的优势。有些对象甚至无法适应TLAB内。
您可以使用“-XX:TLABSize”标志设置TLAB的大小,但通常我不建议您调整这些设置,除非您真正发现可以通过此解决问题。

谢谢。1)当线程分配TLAB时,它仍然必须获取锁定,以便竞争线程不会在第一个线程分配的相同区域分配TLAB。这个假设正确吗?2)在TLAB之外分配对象是否总是昂贵的,因为必须为每个无法适合TLAB的新对象分配锁定? - user1745356
2
想象一下线程1从偏移量0到99声明了一个TLAB,而线程2则从偏移量100到199声明了一个TLAB。合同规定,一旦声明,线程2就不能在0-99中分配,线程1也不能在100-199中分配。没有线程可以将此空间作为其未来的分配缓冲区。这样,如果每个对象占用一个假设的插槽,每个线程都可以分配100个对象而无需同步。在TLAB之外进行分配并不是非常昂贵,但显然比在TLAB内更昂贵,因为它需要与可能同时运行的其他线程进行通信。 - Rafael Winterhalter
抱歉,如果我的问题不清楚,我会尝试用另一种方式表达——如果两个竞争的线程想要为接下来的100个对象分配内存并且下一个可用内存地址从100开始,那么第一个获取锁的线程将获得从100到199的地址,第二个线程将获得200-299。这正确吗? - user1745356
4
是的(不是通过锁来实现,而是使用某种CAS例程)。如果没有TLAB,线程需要为每个分配进行“双重检查”。有了TLAB,它可以在不进行任何额外检查的情况下分配多达100个实例。 - Rafael Winterhalter
我现在明白了。非常感谢。我想我需要阅读关于CAS例程的资料。 - user1745356
基本上,TLAB是一个“thread_local”区域或“thread_local”对象池。 - KeyC0de

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接