JVM面试题
- 面试官: JVM是怎么解决多线程new对象分配空间的
- 我:
JVM 通过 TLAB(线程本地分配缓冲区)+ CAS + Eden 区分配,实现多线程高效创建对象,尽量避免锁竞争。
- 什么是 TLAB
- 每一个线程都有一小块“私有内存”在 Eden 里。线程创建对象优先在自己的 TLAB 里分配
1
2
3Eden 区:
[ TLAB-线程1 ][ TLAB-线程2 ][ TLAB-线程3 ][ 公共区域 ]
- 每一个线程都有一小块“私有内存”在 Eden 里。线程创建对象优先在自己的 TLAB 里分配
- TLAB 不够了怎么办
- 重新申请一个 TLAB(优先)
- 分配到共享 Eden(用 CAS)
- 什么是 TLAB
- 面试官: 你刚才说线程私有的对象会分配到栈中,什么对象是线程私有的?
- 我:
满足以上三个条件的就是线程私有的对象:
- 只在方法内部使用
- 没有返回
- 没有赋值给共享变量
逃逸分析判断对象分配
- 什么是逃逸分析:逃逸分析(Escape Analysis)是 JVM 在运行时分析对象是否被外部访问的一种优化手段,用来判断对象的作用范围,从而决定是否进行栈上分配、锁消除、标量替换等优化。
1
2
3
4
5
6
7
8
9
10
11对象创建
↓
是否逃逸?
↓
┌───────────────┬───────────────┐
│ 不逃逸 │ 逃逸 │
├───────────────┼───────────────┤
│ 线程私有 ✔ │ 非线程私有 ❌ │
│ 可栈上分配 │ 必须在堆 │
│ 可锁消除 │ 可能需要加锁 │
└───────────────┴───────────────┘
- 面试官: 介绍一下JMM
- 我:
JMM 是 Java 定义的多线程内存访问规则,用来保证共享变量在多线程下的正确性
- JMM解决了线程的三大问题
- 可见性问题 (线程 A 修改变量,线程 B 看不到)
- 原子性问题 (i++ 不是原子性)
- 有序性问题(指令重排)
- JMM 的核心模型
- 主内存(Main Memory) → 所有线程共享
- 工作内存(Working Memory) → 每个线程私有
- 变量访问流程
主内存 → 工作内存 → 线程操作 → 写回主内存❗ 线程不能直接操作主内存
❗ 必须通过工作内存 - 什么是 happens-before
happens-before 是用来判断“线程之间操作是否可见、是否有序”的规则- 例如 A happens-before B
- A 一定先执行
- A 的结果对 B 可见
- 例如 A happens-before B
- JMM解决了线程的三大问题
- 面试官: volatile 可以保证原子性吗?
- 我:
volatile 不保证原子性
✅ 只保证可见性 + 有序性保证原子性需要加锁!!!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Little Monste'Blog!
评论









