TLAB: Thread Local Allocation Buffer HotSpot虚拟机带的
分配内存时会存在并发问题,可以通过(1)CAS (2)TLAB解决。TLAB是虚拟机在堆内存的Eden区划分出来的一块专用空间,是线程专属的。
引子: Java堆内存是线程共享的?你确定吗?
- 部分正确:堆中的Eden区存在一种为了解决分配内存时的并发问题而设计的TLAB。该区域为每个线程私有的区域。但是注意,TLAB对于不同线程的对象分配这个动作是独享的,但对于TLAB区域的读取是共享的!
- 大对象分配:遇到TLAB中无法分配的大对象,还是会尝试分配大对象到Eden或老年代,但注意没有了TLAB,向那里面分配对象需要进行线程的同步控制!这也很好地解释了为什么小的对象比大的对象分配起来更加高效!
TLAB带来的问题
当分配内存的时候,TLAB内存空间不是特别大,经常会有不够的问题。一般有两种方案:
- 直接在堆中分配内存
- 废弃当前TLAB,重新申请TLAB空间再次分配
虽然这两种方法都可以,但都不理想。因此,虚拟机定义了一个refill_waste
的值,翻译为“最大浪费空间”。规定如下:
- 大对象:分配的对象内存大于该值的时候,直接在Eden中分配内存。
- 小对象:当该对象的内存小于该值的时候,会废弃当前TLAB,重新创建TLAB为其分配内存。