TLAB refill是否频繁取决于-XX:TLABRefillWasteFraction设定的剩余空间准入阈值,而非TLAB总大小;默认值64表示仅当对象≤当前剩余空间/64时才允许分配,否则触发refill或fallback,易造成隐性浪费。

TLAB 重新装载(refill)是否频繁,不取决于 TLAB 总大小,而取决于每次 refill 前“被丢弃的剩余空间”占当前 TLAB 容量的比例。这个比例阈值,就是 -XX:TLABRefillWasteFraction 控制的核心。
它真正决定什么
该参数不是设置“浪费多少字节才 refill”,而是定义“对象大小需小于 TLAB 剩余空间的几分之一,才能放进当前 TLAB”。默认值为 64,即:只有当对象 ≤ 当前 TLAB 剩余空间 / 64 时,才允许分配进该 TLAB;否则直接拒绝,触发 refill 或 fallback 到 Eden 区。
换句话说,它设定了 TLAB “临界填充利用率”的下限——哪怕还剩 190KB,一个 120KB 的对象(> 190/64 ≈ 3KB)也会被拒,造成大量隐性浪费和 refill。
调大还是调小?看分配特征
- 调小值(如 32、16):放宽准入门槛,允许更大对象进入当前 TLAB,提升单次 TLAB 利用率,减少 refill 次数。适合对象尺寸较集中、突发流量中存在中等偏大(但仍在 TLAB 容量内)对象的场景。
- 调大值(如 128、256):更保守,只让极小对象进来,避免因一个稍大对象导致整块剩余空间作废。适合对象极小且高度离散(比如大量 16–64 字节缓存 key)、TLAB 剩余空间极易碎片化的场景。
配合 -XX:+PrintTLAB 验证效果
加参数 -XX:+PrintTLAB -Xlog:gc+tlab=debug(JDK 10+)或 -XX:+PrintTLAB(旧版),观察日志中的 waste 和 refill 字段:
- 若 waste% 持续高于 5%,且日志中频繁出现 “slow path allocation”,说明当前 RefillWasteFraction 过高,对象总被拒,应适当调小;
- 若 refill/s 突然下降但 GC 后 Eden 碎片上升、humongous allocation 增多,可能是调得过小,导致单个大对象挤占过多 TLAB,反而加剧 Eden 头部竞争,此时应回调至平衡点(建议从 32 或 48 起试)。
不要脱离 ResizeTLAB 单独硬调
固定 TLAB 大小(-XX:TLABSize)时调 RefillWasteFraction 效果有限,因为剩余空间绝对值会随负载波动。推荐组合使用:
- -XX:+ResizeTLAB(JDK8+ 默认开启,务必确认);
- -XX:TLABWasteTargetPercent=1,驱动 JVM 主动压缩平均浪费;
- -XX:TLABRefillWasteFraction=32,作为更积极的准入策略补充。
三者协同,才能让 TLAB 在突发小对象场景下既少 refill,又不堆出碎片。

















