如何利用GC日志中的Allocation Failure追踪因TLAB空间短缺引发的年轻代回收频繁问题?
- 内容介绍
- 文章标签
- 相关推荐
本文共计711个文字,预计阅读时间需要3分钟。
分配给F的样式为红色
看 GC 日志中 Eden 区的回收效率是否异常高
TLAB 分配失败通常不伴随 Eden 大量存活对象,因此 Minor GC 后 Eden 使用量应极低,且 Survivor 区几乎无对象晋升。典型日志模式如下:
-
GC 前 Eden 占用率很高(如 95%+),但 GC 后骤降至 1%~5%,例如:
[PSYoungGen: 1280509K->5120K(1308160K)] - 每次 GC 回收掉 99% 以上 Eden 对象,说明对象生命周期极短,且未在 TLAB 外触发大块分配
- Survivor 区使用量长期稳定在极小值(如几 KB),且老年代占用几乎零增长,排除晋升压力
查日志中是否频繁出现 “TLAB” 相关关键词(JDK 10+ 更明显)
从 JDK 10 起,开启 -Xlog:gc+alloc=debug 或 -Xlog:gc+tlab=debug 可输出 TLAB 分配详情。关键线索包括:
- 日志中出现
TLAB waste、TLAB refill、slow path allocation等字样 - 大量
TLAB allocation failed记录,紧接着就是GC (Allocation Failure) - 同一秒内多次 Minor GC(如间隔
结合对象分配速率与 TLAB 大小估算是否匹配
通过日志可算出平均对象分配速率(如 10.63 MB/sec),再结合 JVM 实际 TLAB 大小(默认约 Eden 的 1%)判断是否过小:
- 用
-XX:+PrintGCDetails+-XX:+PrintTLAB查看每次 GC 前后 TLAB 统计(JDK 8 可用;JDK 11+ 需配合-Xlog:gc+tlab) - 若观察到
TLABs: allocated = X, refilled = Y, waste = Z KB,且waste持续 >30%,说明 TLAB 设置不合理(过大导致浪费,过小导致频繁 refill) - 常见调优:增大 TLAB(
-XX:TLABSize=512k)或启用自适应(默认开启),禁用则用-XX:-UseTLAB(仅用于验证)
排除其他 Allocation Failure 常见原因,聚焦 TLAB
确认不是以下更典型的触发源,才能锁定 TLAB 问题:
- Eden 总空间持续紧张(GC 后 Eden 剩余仍低于 10%,且老年代缓慢上涨)→ 属于堆整体偏小,非 TLAB
- 日志中出现大对象直接分配到老年代(
ParNew: ... promotion failed或desired survivor size超限)→ 是对象大小或 Survivor 容量问题 - Full GC 频繁伴随 Allocation Failure → 多数因老年代碎片或空间不足,与 TLAB 无关
- CPU 使用率高但 GC 耗时低、次数极高 → 更符合多线程争抢 TLAB refill 的特征
本文共计711个文字,预计阅读时间需要3分钟。
分配给F的样式为红色
看 GC 日志中 Eden 区的回收效率是否异常高
TLAB 分配失败通常不伴随 Eden 大量存活对象,因此 Minor GC 后 Eden 使用量应极低,且 Survivor 区几乎无对象晋升。典型日志模式如下:
-
GC 前 Eden 占用率很高(如 95%+),但 GC 后骤降至 1%~5%,例如:
[PSYoungGen: 1280509K->5120K(1308160K)] - 每次 GC 回收掉 99% 以上 Eden 对象,说明对象生命周期极短,且未在 TLAB 外触发大块分配
- Survivor 区使用量长期稳定在极小值(如几 KB),且老年代占用几乎零增长,排除晋升压力
查日志中是否频繁出现 “TLAB” 相关关键词(JDK 10+ 更明显)
从 JDK 10 起,开启 -Xlog:gc+alloc=debug 或 -Xlog:gc+tlab=debug 可输出 TLAB 分配详情。关键线索包括:
- 日志中出现
TLAB waste、TLAB refill、slow path allocation等字样 - 大量
TLAB allocation failed记录,紧接着就是GC (Allocation Failure) - 同一秒内多次 Minor GC(如间隔
结合对象分配速率与 TLAB 大小估算是否匹配
通过日志可算出平均对象分配速率(如 10.63 MB/sec),再结合 JVM 实际 TLAB 大小(默认约 Eden 的 1%)判断是否过小:
- 用
-XX:+PrintGCDetails+-XX:+PrintTLAB查看每次 GC 前后 TLAB 统计(JDK 8 可用;JDK 11+ 需配合-Xlog:gc+tlab) - 若观察到
TLABs: allocated = X, refilled = Y, waste = Z KB,且waste持续 >30%,说明 TLAB 设置不合理(过大导致浪费,过小导致频繁 refill) - 常见调优:增大 TLAB(
-XX:TLABSize=512k)或启用自适应(默认开启),禁用则用-XX:-UseTLAB(仅用于验证)
排除其他 Allocation Failure 常见原因,聚焦 TLAB
确认不是以下更典型的触发源,才能锁定 TLAB 问题:
- Eden 总空间持续紧张(GC 后 Eden 剩余仍低于 10%,且老年代缓慢上涨)→ 属于堆整体偏小,非 TLAB
- 日志中出现大对象直接分配到老年代(
ParNew: ... promotion failed或desired survivor size超限)→ 是对象大小或 Survivor 容量问题 - Full GC 频繁伴随 Allocation Failure → 多数因老年代碎片或空间不足,与 TLAB 无关
- CPU 使用率高但 GC 耗时低、次数极高 → 更符合多线程争抢 TLAB refill 的特征

