新概念: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();
}
}
}