JVM 09.4 執行時資料區 堆 執行緒獨佔區域 TLAB
阿新 • • 發佈:2020-07-17
版權宣告:源出處:尚矽谷JVM
部落格來源於大佬整理
新概念:TLAB(堆當中的執行緒私有快取區域)
為什麼有TLAB(Thread Local Allocation Buffer)
- 眾所周知堆區是執行緒共享區域,任何執行緒都可以訪問到堆區中的共享資料。由於物件例項的建立在JVM中非常頻繁,因此在併發環境下從堆區中劃分記憶體空間是執行緒不安全的。
- 一般為了避免多個執行緒操作同一地址,需要使用加鎖等機制,進而影響分配速度。
- 為了解決這一問題,TLAB應運而生。
什麼是TLAB
- 從記憶體模型而不是垃圾收集的角度,對Eden區域繼續進行劃分,JVM為每個執行緒分配了一個私有快取區域,它包含在Eden空間內
- 多執行緒同時分配記憶體時,使用TLAB可以避免一系列的非執行緒安全問題,同時還能夠提升記憶體分配的吞吐量,因此我們可以將這種記憶體分配方式稱之為快速分配策略
- 所有OpenJDK衍生出來的JVM都提供了TLAB的設計
TLAB說明
- 儘管不是所有的物件例項都能夠在TLAB中成功分配記憶體,單JV明確是是將TLAB作為記憶體分配的首選
- 在程式中,開發人員可以通過選項“-XX:UseTLAB“ 設定是夠開啟TLAB空間
- 預設情況下,TLAB空間的記憶體非常小,僅佔有整個EDen空間的1%,當然我們可以通過選項 ”-XX:TLABWasteTargetPercent“ 設定TLAB空間所佔用Eden空間的百分比大小
- 一旦物件在TLAB空間分配記憶體失敗時,JVM就會嘗試著通過使用加鎖機制確保資料操作的原子性,從而直接在Eden空間中分配了記憶體
程式碼演示
- 執行程式後,終端輸入jsp檢視TLABArgsTest程序id
- jinfo -flag UseTLAB 64566(程序id),輸出-XX:+UseTLAB,證明TLAB預設是開啟的
/**
* 測試-XX:UseTLAB引數是否開啟的情況:預設情況是開啟的
*/
public class TLABArgsTest {
public static void main(String[] args) {
System.out.println("我只是來打個醬油~");
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}