堆空间-TLAB

TLAB

:::primary

参考博客:

JVM - TLAB

在TLAB中创建的对象,如何被其他线程共享?

浅析java中的TLAB

:::

什么是 TLAB?

  • 名称:

    • 全称:TLAB(Thread Local Allocation Buffer)
    • 译名:线程本地缓存
  • 定义:[堆中的 伊甸园区 分配给线程的一块较小的“私有”空间]{.red}

    • 在伊甸园区中划分 TLAB 采用的也是指针碰撞的方式
    • TLAB 内部分配对象时采用的依然是指针碰撞的方式
  • 特点:

    • TLAB 空间非常小,仅占用伊甸园区的 1% 大小

    • [线程每次创建对象优先在 TLAB 区域创建]{.red}

    • [线程每次在 TLAB 中创建对象时,其余线程是无法抢占 TLAB 执行的]{.red}

    • TLAB 无法分配足够的空间给新对象时:

      • [TLAB 剩余的空间大于设定的最大浪费空间(阈值):新对象直接在伊甸园区的公共部分进行创建]{.red}

      • [TLAB 剩余的空间小于设定的最大浪费空间(阈值):重新提供给线程一块 TLAB 让其创建对象]{.red}

        :::info

        ① 如果新分配的 TLAB 依然无法容纳新对象,那么该对象就需要在伊甸园公共区域创建

        ② 如果在伊甸园的公共区域创建对象,那就意味着需要其他的方式确保分配过程的安全(诸如CAS加锁)

        :::

  • 命令:

    • [-XX:TLABWasteTargetPercent 设置 TLAB 区域所占空间的百分比]{.blue}

为什么要使用 TLAB?

  • 引入:
    • 多线程情况下,如何确保创建对象时的线程安全,不会被其余线程抢占执行?
    • 当前线程刚为对象分配好空间,还没来得及将引用指向内存,其余线程抢占执行,覆盖了刚才创建的对象
    • 这种情况是非常有可能发生的
  • 方式:
    • [给每个线程为对象分配内存的动作做同步处理]{.red},确保其余线程不会访问
      • [线程分配动作同步带来的缺陷显然就是程序性能的下降]{.green}
    • [给每个线程分配“私有”的堆空间,每次线程都在这个“私有”的空间中创建对象]{.red},确保其余线程不会访问
      • [“私有”空间并不是真正的线程私有,线程仅在分配对象空间时独占这块区域,其余时候所有线程都可以访问这块区域]{.green}
      • [线程在 TLAB 上分配对象时并不会将这块区域上锁,所以不会因为同步造成性能下降]{.red}

TLAB 原理是什么?

Author: Fuyusakaiori
Link: http://example.com/2021/09/23/jvm/runtime/heapspace/TLAB/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.