1. 类加载检查 (Loading & Init Check)
- 动作 :检查
new指令的参数是否能在元空间(方法区)定位到一个类的符号引用。 - 核心逻辑 :确认这个类是否已经走完了"加载、验证、准备、解析、初始化"全过程。如果没有,必须先执行类加载。
- 产物:确保"模具"(类元数据)在元空间里是可用的、绿灯状态的。
2. 分配内存 (Memory Allocation)
- 动作 :在 Java 堆 中划出一块确定大小的内存给新对象。
- 关键技术 :
- 指针碰撞 (Bump the pointer):内存规整时使用。
- 空闲列表 (Free list):内存碎片化时使用。
- TLAB (Thread Local Allocation Buffer):为了解决并发安全,每个线程先在自己的"小私库"里领地。
3. 零值初始化 (Zeroing Out)
- 动作 :将分配到的内存空间(不包括对象头 )都初始化为零值(如
int为0,boolean为false,引用类型为null)。 - 意义:这保证了 Java 对象的实例字段在代码层不赋初值也能直接使用。这就是为什么你在类里定义的成员变量有默认值,而方法里的局部变量不赋值就会报错的原因。
4. 设置对象头 (Setting Object Header)
- 动作:填写对象的"身份证"。
- 内容 :
- Mark Word:哈希码、GC 分代年龄、锁状态标志。
- Klass Pointer:指向元空间里类元数据的指针。
- 物理意义:此时,这个内存块真正变成了一个"有身份"的 Java 对象。
5. 对象初始化 (Executing <init>)
- 动作:执行程序员写的构造函数、代码块,为成员变量赋上真正的业务初始值。
- 执行顺序 :父类变量初始化 →\rightarrow→ 父类构造器 →\rightarrow→ 子类变量初始化 →\rightarrow→ 子类构造器。
- 最终状态:此时,对象才真正按照你的意图"装修"完毕,可以投入使用了。