在开始文章之前,我想在座的各位已经了解了JVM创建对象和分配内存地址的过程,也知道了JVM的内存划分。本着人道主义,贴张图给大家对比一下。JVM内存结构、堆内存划分结构、堆区分配,有没有多线程安全问题?答:可能存在;新对象();我们都知道上面的操作需要在堆内存中开辟一块内存空间,那么想一想这个问题,堆区是所有线程共享的,那么当JVM频繁创建对象的时候,开辟是否存在安全问题并发条件下堆内存中的空间?所以为了解决这个问题,我们首先想到的就是加锁,但是加锁有一个问题,就是影响性能。TLAB(ThreadLocalAllocationBuffer)的出现就是基于上述问题,导致了TLAB。强行翻译一下,就是线程局部分配缓冲区。首先我们看图中的语句:在堆内存中分配空间,首先是在eden区分配,而不是直接在老年代分配。内存分配结束后,不会进行一次YongGC。如果对象没有被回收,那么它的存活计数将为+1。如果数量达到15,那么这个对象就会被提升到老年代。那么我们知道对象分配首先是在eden区进行的,所以上图就不难理解了。我们在eden区划分一个区域,我们称之为TLAB。每个TLAB都是现成的private,所以并发创建其实不需要在创建对象的时候进行加锁等操作,这样就解决了现有的安全问题。如果分配的TLAB空间用完了或者对象需要的内存空间大于TLAB所能提供的空间,那么只能在publiceden区或者老年代分配内存空间。总结1.JVM更喜欢TLAB来分配内存空间;2、TLAB占整个eden区的1%,这个值也可以通过参数自定义;通过这个问题,可以推导出另一个问题。严格意义上来说,heaparea不被线程共享。
