今天,又是乾貨滿滿的一天。這是全網最硬核 JVM 系列的開篇,首先從 TLAB 開始。因爲文章很長,每一個人閱讀習慣不一樣,因此特此拆成單篇版和多篇版git
- 全網最硬核 JVM TLAB 分析(單篇版不包含額外加菜)
- 全網最硬核 JVM TLAB 分析 1. 內存分配思想引入
- 全網最硬核 JVM TLAB 分析 2. TLAB生命週期與帶來的問題思考
- 全網最硬核 JVM TLAB 分析 3. JVM EMA指望算法與TLAB相關JVM啓動參數
- 全網最硬核 JVM TLAB 分析 4. TLAB 基本流程全分析
- 全網最硬核 JVM TLAB 分析 5. TLAB 源代碼全解析
- 全網最硬核 JVM TLAB 分析 6. TLAB 相關熱門Q&A彙總
- 全網最硬核 JVM TLAB 分析(額外加菜) 7. TLAB 相關 JVM 日誌解析
- 全網最硬核 JVM TLAB 分析(額外加菜) 8. 經過 JFR 監控 TLAB
6. JVM 中的指望計算 EMA
在上面提到的 TLAB 大小設計的時候,咱們常常提到指望。這個指望是根據歷史數據計算得出的,也就是每次輸入採樣值,根據歷史採樣值得出最新的指望值。不只 TLAB 用到了這種指望計算,GC 和 JIT 等等 JVM 機制中都用到了。這裏咱們來看一種 TLAB 中常常用到的 EMA(Exponential Moving Average 指數平均數) 算法:github
EMA 算法的核心在於設置合適的最小權重,咱們假設一個場景:首先採樣100個 100(算法中的前 100 個是爲了排除不穩定的干擾,咱們這裏直接忽略前 100 個採樣),以後採樣 50 個 2,最後採樣 50 個 200,對於不一樣的最小權重,來看一下變化曲線。算法
能夠看出,最小權重越大,變化得越快,受歷史數據影響越小。根據應用設置合適的最小權重,可讓你的指望更加理想。數組
這塊對應的源代碼:gcUtil.hpp
的 AdaptiveWeightedAverage
類。緩存
7. TLAB 相關的 JVM 參數
這裏僅僅是列出來,並附上簡介,看不懂不要緊,以後會有詳細分析,幫助你理解每個參數。等你理解後,這個小章節就是你的工具書啦~~ 如下參數以及默認值基於 OpenJDK 17函數
7.1. TLABStats(已過時)
從 Java 12 開始已過時,目前已經沒有相關的邏輯了。以前是用於 TLAB 統計數據從而更好地伸縮 TLAB 可是性能消耗相對較大,可是如今主要經過 EMA 計算了。工具
7.2. UseTLAB
說明:是否啓用 TLAB,默認是啓用的。性能
默認:truefetch
舉例:若是想關閉:-XX:-UseTLAB
優化
7.3. ZeroTLAB
說明:是否將新建立的 TLAB 內的全部字節歸零。咱們建立一個類的時候,類的 field 是有默認值的,例如 boolean 是 false,int 是 0 等等,實現的方式就是對分配好的內存空間賦 0。設置 ZeroTLAB 爲 true 表明在 TLAB 申請好的時候就賦 0,不然會在分配對象並初始化的時候賦 0.講道理,因爲 TLAB 分配的時候會涉及到 Allocation Prefetch 優化 CPU 緩存,在 TLAB 分配好以後馬上更新賦 0 對於 CPU 緩存應該是更友好的,而且,若是 TLAB 沒有用滿,填充的 dummy object 其實依然是 0 數組,至關於大部分不用改。這麼看來,開啓應該更好。可是ZeroTLAB 默認仍是不開啓的。
默認:false
舉例:-XX:+ZeroTLAB
7.4. ResizeTLAB
說明:TLAB 是不是可變的,默認爲是,也就是會根據線程歷史分配數據相關 EMA 計算出每次指望 TLAB 大小並以這個大小爲準申請 TLAB。
默認:true
舉例:若是想關閉:-XX:-ResizeTLAB
7.5. TLABSize
說明:初始 TLAB 大小。單位是字節
默認:0, 0 就是不主動設置 TLAB 初始大小,而是經過 JVM 本身計算每個線程的初始大小
舉例:-XX:TLABSize=65536
7.6. MinTLABSize
說明:最小 TLAB 大小。單位是字節
默認:2048
舉例:-XX:TLABSize=4096
7.7. TLABAllocationWeight
說明: TLAB 初始大小計算和線程數量有關,可是線程是動態建立銷燬的。因此須要基於歷史線程個數推測接下來的線程個數來計算 TLAB 大小。通常 JVM 內像這種預測函數都採用了 EMA 。這個參數就是 圖06 中的最小權重,權重越高,最近的數據佔比影響越大。TLAB 從新計算大小是根據分配比例,分配比例也是採用了 EMA 算法,最小權重也是 TLABAllocationWeight
默認:35
舉例:-XX:TLABAllocationWeight=70
7.8. TLABWasteTargetPercent
說明:TLAB 的大小計算涉及到了 Eden 區的大小以及能夠浪費的比率。TLAB 浪費指的是上面提到的從新申請新的 TLAB 的時候老的 TLAB 沒有分配的空間。這個參數其實就是 TLAB 浪費佔用 Eden 的百分比,這個參數的做用會在接下來的原理說明內詳細說明
默認:1
舉例:-XX:TLABWasteTargetPercent=10
7.9. TLABRefillWasteFraction
說明: 初始最大浪費空間限制計算參數,初始最大浪費空間限制 = 當前指望 TLAB 大小 / TLABRefillWasteFraction
默認:64
舉例:-XX:TLABRefillWasteFraction=32
7.10. TLABWasteIncrement
說明: 最大浪費空間限制並非不變的,在發生 TLAB 緩慢分配的時候(也就是當前 TLAB 空間不足以分配的時候),會增長最大浪費空間限制。這個參數就是 TLAB 緩慢分配時容許的 TLAB 浪費增量。單位不是字節,而是 MarkWord
個數,也就是 Java 堆的內存最小單元,64 位虛擬機的狀況下,MarkWord
大小爲 3 字節。
默認:4
舉例:-XX:TLABWasteIncrement=4