外观
一句话答案
对象创建五步:类加载检查→内存分配(指针碰撞/空闲列表 + TLAB)→零值初始化→设置对象头→执行构造方法。
核心要点
完整流程(5 步):
- 类加载检查:检查 new 指令的参数是否能在常量池中找到类的符号引用,且该类已加载/解析/初始化
- 内存分配:
- 指针碰撞:内存规整时(Serial/ParNew),移动指针分配
- 空闲列表:内存不规整时(CMS),从列表中找合适块
- 并发安全:TLAB(Thread Local Allocation Buffer)或 CAS+失败重试
- 零值初始化:内存清零(保证字段有默认值)
- 设置对象头:Mark Word(哈希/GC年龄/锁状态)+ 类型指针
- 执行
<init>:调用构造方法,按程序员意愿初始化
TLAB(面试加分点):
- 每个线程预分配一块私有内存(Eden 区的一小块)
- 分配对象时优先在 TLAB 中分配,无需同步
- TLAB 用完再 CAS 竞争分配新 TLAB
追问与易错
追问方向:
- 对象分配在堆上还是栈上?
- TLAB 是什么?为什么需要?
- new 和构造方法的关系?
易错点:
- ❌ new 完对象就能用了——构造方法执行前字段是零值
- ❌ 忽略并发分配的线程安全问题
💡 记忆锚点
new对象五步流水线:查户口(类加载检查)、分房子(指针碰撞或空闲列表,TLAB免排队)、打扫卫生(零值初始化)、贴门牌(设对象头)、装修入住(执行构造方法)。TLAB是每个线程在Eden的私人小金库,分配不用抢锁。