今天,又是干货满满的一天。这是全网最硬核 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