揭開JVM中TLAB中的神秘面紗
本文轉載自微信公眾號「一個程序員的成長」,作者一個程序員的成長。轉載本文請聯系一個程序員的成長公眾號。
在開始文章之前,我這里暫且認為大家已經明白了JVM創建對象分配內存地址的流程,也知道JVM內存劃分。基于人道主義我還是放一張圖吧,大家對照著看。
JVM內存結構
堆內存劃分結構
堆區分配內存是否存在多線程安全問題?
答:可能存在;
new Object();
上述操作我們都知道它最終需要在堆內存中開辟一塊內存空間,那么想這么一個問題,堆區是所有線程共享的,那么在JVM頻繁創建對象的時候,并發情況下在堆內存中開辟空間是不是存在安全問題。
那么為了解決這個問題我們首先想到的就是加鎖,但是加鎖存在一個問題,就是影響性能。
TLAB出現(Thread Local Allocation Buffer)
基于上面的問題,從而引出了TLAB,強行翻譯一下就是線程本地分配緩沖區,首先呢先看張圖
聲明:在堆內存中分配空間,首先是在eden區進行分配,并不是直接分配在老年代,內存分配結束之后,沒進行一次Yong GC,如果對象沒有被回收,那么他的存活次數就會 +1,如果這個次數達到15次,那么這個對象晉升到老年代。
那么我們知道了對象分配首先是在eden區進行的,那么也不難理解上面的圖,我們在eden區域劃分出來一塊區域,我們稱之為TLAB,每一個TLAB都是現成私有的,那么并發創建對象的時候其實也就不需要進行加鎖這樣的操作了,這樣現成安全問題就解決了。
如果分配的這些TLAB空間被使用完了或者對象所需要額內存空間大于TLAB所能提供的空間,那么只能在公用的eden區或者老年代分配內存空間了。
總結
- 1、JVM首選TLAB進行內存空間的分配;
- 2、TLAB占用整個eden區域的1%,這個值也可以通過參數自定義;
通過這個問題也可以推理出另外一個問題,堆區在嚴格意義上說不是線程共享的。