• 面试官: JVM是怎么解决多线程new对象分配空间的
  • 我:

    JVM 通过 TLAB(线程本地分配缓冲区)+ CAS + Eden 区分配,实现多线程高效创建对象,尽量避免锁竞争。

    1. 什么是 TLAB
      • 每一个线程都有一小块“私有内存”在 Eden 里。线程创建对象优先在自己的 TLAB 里分配
        1
        2
        3
        Eden 区:

        [ TLAB-线程1 ][ TLAB-线程2 ][ TLAB-线程3 ][ 公共区域 ]
    2. TLAB 不够了怎么办
      • 重新申请一个 TLAB(优先)
      • 分配到共享 Eden(用 CAS)
  • 面试官: 你刚才说线程私有的对象会分配到栈中,什么对象是线程私有的?
  • 我:
    1. 满足以上三个条件的就是线程私有的对象:

      • 只在方法内部使用
      • 没有返回
      • 没有赋值给共享变量
    2. 逃逸分析判断对象分配

      • 什么是逃逸分析:逃逸分析(Escape Analysis)是 JVM 在运行时分析对象是否被外部访问的一种优化手段,用来判断对象的作用范围,从而决定是否进行栈上分配、锁消除、标量替换等优化。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    对象创建

    是否逃逸?

    ┌───────────────┬───────────────┐
    │ 不逃逸 │ 逃逸 │
    ├───────────────┼───────────────┤
    │ 线程私有 ✔ │ 非线程私有 ❌ │
    │ 可栈上分配 │ 必须在堆 │
    │ 可锁消除 │ 可能需要加锁 │
    └───────────────┴───────────────┘