JVM:TLAB

简介

TLAB: Thread Local Alloc Buffer 在设置了参数 -XX:UseTLAB之后启用。在线程初始化的过程当中,同时也会申请一块内存,只给当前线程使用。TLAB只有在“分配”这个动作上是线程独占的,而在使用/收集意义上都还是让所有线程共享的;使用上的共享并不需要做任何额外检查。
所谓TLAB其实就是这样的一个东西:(简化伪代码)

struct ThreadLocalAllocBuffer {
  HeapWord* _start;
  HeapWord* _top;
  HeapWord* _end;
};

每个线程会从Eden分配一大块空间,例如说100KB,作为自己的TLAB。这个start是TLAB的起始地址,end是TLAB的末尾,然后top是当前的分配指针。显然start <= top < end。

JVM如何为对象分配内存

在Eden分配空间时,用的是 bump-the-pointer(指针碰撞法) 方式来分配,但由于Eden是所有Java线程所共享的,在bump pointer时采用CAS方式才可以保证安全;而当每个线程从Eden分配到一块空间当作TLAB来用之后,在TLAB里分配小块空间同样是bump-the-pointer(上面示意的top指针)则不需要加锁。

如果TLAB分配的内存用完了怎么办?

当一个Java线程在自己的TLAB中分配到尽头之后,再要分配就会出发一次 “TLAB refill” ,也就是说之前自己的TLAB就“不管了”(所有权交回给共享的Eden),然后重新从Eden里分配一块空间作为新的TLAB。把那块空间的控制权归还给普通的Eden,里面的对象该怎样还是怎样。通常情况下,在TLAB中分配多次才会填满TLAB、触发TLAB refill,这样使用TLAB分配就比直接从共享部分的Eden分配要均摊(amortized)了同步开销,于是提高了性能。

如何GC?

到触发GC的时候,无论是minor GC还是full GC,要收集Eden的时候里面的空间无论是属于某个线程的TLAB还是不属于任何TLAB都一视同仁,把Eden当作一个整体来收集里面的对象——把活的对象拷贝到survivor space(或者直接晋升到Old Gen)。在GC结束之后,每个Java线程又会重新从Eden分配自己的TLAB。周而复始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值