Java堆的区域都是线程共享的吗?
当你听到这个问题的时候,你首先想到的是什么呢?
let me tell you
面试官其实问这个的时候就是在看你对堆的了解程度,你只知道是用来放对象实例的,那面试官对你表现觉得不算非常满意;但是如果你知道TLAB,并且知道它的原理和问题,那面试官就会觉得:这小伙子不一般,我得再多深入了解了解,可以考虑当我的好助手
首先,你得肯定回答,没错,堆是全局共享的,但是会存在一些问题
就是多个线程在堆上同时申请空间,如果在并发的场景中,两个线程先后把对象引用指向了同一个内存区域,那可能就会出现问题;为了解决这个问题呢,就得进行同步控制,说到同步控制,就会影响到效率
就拿Hotspot来举例子,它的解决方案是每个线程在堆中都预先分配一小块内存,然后再给对象分配内存的时候,先在这块“私有内存”进行分配,这块用完之后再去分配新的“私有内存”,这就是TLAB分配
你也看到了,我加引号了,它并不是真正意义上的私有,而是表面上的私有
它是从堆内存划分出来的,有了TLAB技术,堆内存并不是完完全全的线程共享,每个线程在初始化的时候都会去内存中申请一块TLAB
切记:并不是TLAB区域的内存其它线程完全无法访问,其它线程也是可以读取的,只不过无法在这个区域分配内存而已
说到这的时候,也给面试官一个眼神,说明我的干货还没完,我还能继续吹
难道TLAB很完美吗?所谓,金无足赤人无完人,肯定有他的问题所在
我们知道TLAB是线程特有的,它的内存区域不是很大,所以会出现一些不够用的情况,比如一个线程的TLAB的空间有100KB,其中已经使用了80KB,如果还需要再分配一个30KB的对象,则无法直接在TLAB上分配