JVM中不同垃圾收集器在内存分配中对TLAB(线程局部分配缓冲区)的协同控制

轻瑶君_9104

轻瑶君_9104

2026-06-05

1010人浏览

原创

tlab refill失败时,jvm尝试为线程重新分配新tlab但eden空间不足,触发young gc;失败后线程降级至共享eden分配,导致内存不连续、填充对象堆积和碎片化损耗。

jvm中不同垃圾收集器在内存分配中对tlab(线程局部分配缓冲区)的协同控制

TLAB 是 JVM 为提升多线程对象分配效率而设计的底层机制,它本身不依赖特定 GC 算法,但不同垃圾收集器在 Eden 区管理、TLAB 分配策略和 refill 行为上存在实质性差异。理解这些协同关系,能帮你更准确诊断分配延迟、GC 波动或内存浪费问题。

主流 GC 对 TLAB 的基础支持情况

所有 OpenJDK 衍生的 JVM(HotSpot)默认启用 TLAB,且绝大多数 GC 都原生兼容 TLAB,但支持深度和日志粒度不同:

  • G1 GC:完全支持 TLAB,每个线程在 Eden Region 中划分私有 TLAB;支持动态 resize 和 waste 控制;-XX:+PrintTLAB 日志完整,refill 和 waste 指标可直接观测。
  • Parallel GC(吞吐量优先):高度优化 TLAB,是 TLAB 利用率最高的 GC 之一;默认 aggressive refill,TLAB 大小自适应快;但日志中 TLAB 统计较简略(需配合 -XX:+PrintGCDetails 手动推断)。
  • ZGC(低延迟):JDK 15+ 默认启用 TLAB,但早期版本(如 JDK 11/12)部分构建默认禁用 TLAB 日志输出;ZGC 的染色指针与元数据结构导致大对象判定更敏感,TLAB fallback 更频繁;需用 -Xlog:gc+alloc=debug 查看实际分配路径。
  • Shenandoah:支持 TLAB,但因并发移动特性,在 refill 时需额外处理引用更新;TLAB 大小通常比 G1 更保守,避免在移动阶段引发过多转发指针开销。

TLAB refill 与 GC 触发的耦合行为

TLAB 不是独立内存池,它始终从 Eden 区“借”空间。当线程需要 refill 新 TLAB 时,JVM 必须确保 Eden 有足够连续空间——这会直接受当前 GC 状态影响:

Happy Oyster
Happy Oyster

一款AI开发辅助工具,主要用于阿里巴巴推出的实时交互式3D世界模型,适合需要提升相关任务效率的用户。

下载
  • Eden 已接近满但尚未触发 Minor GC → refill 可能失败,线程被迫走 slow path(CAS 分配到共享 Eden),此时 slow_allocations 上升,GC 日志中可见 “TLAB waste” 偏高但未触发回收。
  • G1 在 mixed GC 阶段持续回收老年代 Region → Eden 可用空间波动大 → TLAB 分配成功率下降,部分线程频繁 fallback,表现为分配延迟毛刺。
  • ZGC/Shenandoah 的并发标记与移动阶段不阻塞应用线程分配,但 Eden 空间被 GC 线程隐式占用 → TLAB refill 请求可能排队或降级,refill_waste 持续偏高 往往是 GC 并发压力大的信号,而非 TLAB 配置问题。

GC 策略如何影响 TLAB 实际效果

TLAB 效果好不好,不只看是否开启,更取决于 GC 是否让 Eden 保持“易分割、低碎片、响应快”的状态:

  • 使用 Parallel GC 时,若 -XX:MaxGCPauseMillis 设置过低,会导致 GC 频繁但每次回收不彻底 → Eden 碎片增多 → TLAB 分配失败率上升,即使 TLABSize 合理也难改善。
  • G1 的 -XX:G1NewSizePercent 和 -XX:G1MaxNewSizePercent 直接限制 Eden 总容量 → Eden 过小则单个 TLAB 最大大小受限,小线程多的应用容易出现“TLAB 够用但 Eden 不够分”的窘境。
  • ZGC 的 -XX:SoftMaxHeapSize 若设得太接近 -Xmx,会压缩 Eden 可用空间 → TLAB refill 失败率升高,且日志中 humongous allocation 出现更早(因剩余 Eden 连续块变小)。

排查建议:结合 GC 类型看 TLAB 日志关键字段

不要泛泛查 TLAB 是否开启,要按 GC 类型关注真正有效的指标:

  • G1 / Parallel:加 -XX:+PrintGCDetails -XX:+PrintTLAB,重点看每行中的 desired_size(JVM 推荐大小)、refill_waste(每次 refill 浪费字节数)、slow_allocations(共享 Eden 分配次数)。
  • ZGC / Shenandoah:必须用 -Xlog:gc+alloc=debug,搜索 “allocation request” 和 “tlab refill”,观察是否大量 fallback 到 “shared eden” 或触发 “humongous allocation”。
  • 所有 GC 下,若发现 slow_allocations 占总分配 >3%,优先检查 Eden 使用率曲线(用 GCViewer 或 Prometheus + jvm_gc_collection_seconds_count)是否长期高于 85%,而非调大 TLABSize。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

3998

6

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

2026.10.10

40

15

Kratos框架HTTP与gRPC服务开发教程
Kratos框架HTTP与gRPC服务开发教程

本专题围绕Kratos框架双协议服务开发,涵盖HTTP路由与处理器编写、参数获取、gRPC服务实现与客户端调用、metadata上下文传递、encoding编解码注册、统一响应封装、超时控制与流式响应实现方法。

2026.10.10

20

15

Kratos框架Protobuf接口定义与代码生成合集
Kratos框架Protobuf接口定义与代码生成合集

本专题讲解Kratos框架接口定义体系,涵盖proto编写规范、proto add/client/server生成命令、http注解路由、validate校验、OpenAPI文档生成、跨服务proto复用与兼容性设计。

2026.10.10

0

15

C++虚函数怎么定义和调用
C++虚函数怎么定义和调用

C++虚函数是实现运行时多态的重要机制。本专题从virtual关键字的基本用法入手,介绍基类与派生类之间的函数重写、基类指针调用派生类方法,以及动态绑定的执行过程,帮助初学者掌握虚函数的核心语法。

2026.10.10

20

26

C++类与对象的封装方法教程
C++类与对象的封装方法教程

C++封装是面向对象编程的核心特性之一,通过类将数据与操作数据的函数组织在一起,并利用访问权限控制外部访问。本专题介绍类的定义、成员变量、成员函数以及public、private和protected的使用方法,帮助初学者掌握封装的基本原理。

2026.10.10

20

32

C++构造函数定义与调用方法
C++构造函数定义与调用方法

C++构造函数用于初始化类对象,是面向对象编程的重要基础。本专题从构造函数的定义、声明和调用入手,介绍默认构造函数、带参数构造函数、拷贝构造函数及成员初始化列表,帮助初学者掌握对象创建与初始化的基本方法。

2026.10.10

20

16

Kratos框架零基础入门教程
Kratos框架零基础入门教程

本专题整理Kratos框架入门内容,涵盖Go环境准备、kratos CLI安装升级、new命令创建项目、目录结构分层说明、服务启动与双协议端口、依赖下载报错排查,帮助开发者快速跑通第一个Kratos框架微服务应用。

2026.10.10

20

15

C++条件判断语句怎么写
C++条件判断语句怎么写

C++条件判断是控制程序执行流程的重要基础。本专题介绍if、if-else、else if和switch等常见分支语句,结合条件表达式、比较运算符与代码示例,帮助初学者掌握不同场景下的判断逻辑。

2026.10.10

20

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习