今天,又是乾貨滿滿的一天。這是全網最硬核 JVM 系列的開篇,首先從 TLAB 開始。因爲文章很長,每一個人閱讀習慣不一樣,因此特此拆成單篇版和多篇版算法
- 全網最硬核 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
TLAB 是線程私有的,線程初始化的時候,會建立並初始化 TLAB。同時,在 GC 掃描對象發生以後,線程第一次嘗試分配對象的時候,也會建立並初始化 TLAB。 TLAB 生命週期中止(TLAB 聲明週期中止不表明內存被回收,只是表明這個 TLAB 再也不被這個線程私有管理)在:markdown
TLAB 要解決的問題很明顯,儘可能避免從堆上直接分配內存從而避免頻繁的鎖爭用。post
引入 TLAB 以後,TLAB 的設計上,也有不少值得考慮的問題。性能
出現孔隙的狀況:spa
若是無論這些孔隙,因爲 TLAB 僅線程內知道哪些被分配了,在 GC 掃描發生時返回 Eden 區,若是不填充的話,外部並不知道哪一部分被使用哪一部分沒有,須要作額外的檢查,那麼會影響 GC 掃描效率。因此 TLAB 迴歸 Eden 的時候,會將剩餘可用的空間用一個 dummy object 填充滿。若是填充已經確認會被回收的對象,也就是 dummy object, GC 會直接標記以後跳過這塊內存,增長掃描效率。可是同時,因爲須要填充這個 dummy object,因此須要預留出這個對象的對象頭的空間。線程
若是咱們能提早知道在這一輪內每一個線程會分配多少內存,那麼咱們能夠直接提早分配好。可是,這簡直是癡人說夢。每一個線程在每一輪 GC 的分配狀況可能都是不同的:設計
因此,綜合考慮以上狀況,咱們應該這麼實現 TLAB:3d