天天看點

JVM 09.4 運作時資料區 堆 線程獨占區域 TLAB

新概念:TLAB(堆當中的線程私有緩存區域)

為什麼有TLAB(Thread Local Allocation Buffer)

  • 衆所周知堆區是線程共享區域,任何線程都可以通路到堆區中的共享資料。由于對象執行個體的建立在JVM中非常頻繁,是以在并發環境下從堆區中劃分記憶體空間是線程不安全的。
  • 一般為了避免多個線程操作同一位址,需要使用加鎖等機制,進而影響配置設定速度。
  • 為了解決這一問題,TLAB應運而生。

什麼是TLAB

  • 從記憶體模型而不是垃圾收集的角度,對Eden區域繼續進行劃分,JVM為每個線程配置設定了一個私有緩存區域,它包含在Eden空間内
  • 多線程同時配置設定記憶體時,使用TLAB可以避免一系列的非線程安全問題,同時還能夠提升記憶體配置設定的吞吐量,是以我們可以将這種記憶體配置設定方式稱之為快速配置設定政策
  • 所有OpenJDK衍生出來的JVM都提供了TLAB的設計
JVM 09.4 運作時資料區 堆 線程獨占區域 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預設是開啟的
JVM 09.4 運作時資料區 堆 線程獨占區域 TLAB
/**
 * 測試-XX:UseTLAB參數是否開啟的情況:預設情況是開啟的
 */
public class TLABArgsTest {
    public static void main(String[] args) {
        System.out.println("我隻是來打個醬油~");
        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}      
JVM 09.4 運作時資料區 堆 線程獨占區域 TLAB
JVM 09.4 運作時資料區 堆 線程獨占區域 TLAB

TLAB對象配置設定過程

JVM 09.4 運作時資料區 堆 線程獨占區域 TLAB

繼續閱讀