一、前言
上一篇,我们已经知道逃逸分析的作用和优势了,那么今天,我们就来看下TLAB(Thread Local Allocation Buffer)线程本地分配缓存区,在内存结构 一篇中有提到过他
,今天咱们就来细细研究下它。
二、什么是TLAB
我们知道java对象一般都是虚拟机确定对象大小,然后在堆内存中分配空间存放;
因为堆空间是所有线共享的,所以如果当线程并发时,同使需要在堆里开辟空间存放对象,怎么办?
这个问题一般有两种解决方案
三、TLAB的使用
TLAB分配,是HotSpot虚拟机中采用的的方案,这部分TLAB空间其实也是从堆中划分出来的,TLAB仅作用于新生代的Eden,是每个线程独享的,一般情况是很小的,缺省情况下仅占有整个Eden空间的1%(可以通过-XX:TLABSize
设置大小)。
因为是从堆里面分配出来的空间,所以GC和读取数据都是共享的,所以在使用的时候其实没什么区别;
TLAB的本质其实是三个指针管理的区域:start,top 和 end,每个线程都会从Eden分配一块空间;
例如虚拟机分配100KB,作为线程自己的TLAB,其中 start 和 end 是占位用的,标识出 eden 里被这个 TLAB 所管理的区域,卡住eden里的一块空间不让其它线程来这里分配,当一个TLAB用满(分配指针top撞上分配极限end了),就新申请一个TLAB,老的TLAB保持不动。
TLAB的缺点
- TLAB空间大小是固定的,通常都是比较小的,所以对于大一点的对象来说,就是放不下的;
- TLAB空间还剩一点点没有用到,不用又可惜但是又用不到;
- Eden内存不够的时候,再次申请,会导致堆发生GC垃圾回收;
- TLAB允许浪费空间,导致Eden区空间不连续,积少成多,就造成了空间浪费;
JVM中TLAB参数
4.常见相关jvm参数