1. 程式人生 > 實用技巧 >JVM 09.4 執行時資料區 堆 執行緒獨佔區域 TLAB

JVM 09.4 執行時資料區 堆 執行緒獨佔區域 TLAB

版權宣告:源出處:尚矽谷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();
        }
    }
}

TLAB物件分配過程