java对象创建时,jvm先检查类加载状态,再根据堆内存状况选择指针碰撞、空闲列表或tlab分配空间;随后零值初始化字段并设置对象头;最后执行构造方法完成业务初始化。

Java 中对象创建时的内存分配与初始化,是 JVM 在堆中完成的一套有顺序、讲策略的底层动作。整个过程不是简单“划块地、填数据”,而是兼顾线程安全、分配效率和语义正确性的协同执行。
类加载检查先行
执行 new 之前,JVM 先确认类是否已加载、链接和初始化。若未完成,会触发类加载器加载对应 .class 文件,填充方法区中的元数据,并执行静态代码块和静态变量赋值(
堆内存空间分配策略
类信息确定后,JVM 根据堆当前状态选择分配方式:
- 指针碰撞(Bump the Pointer):适用于 Serial、ParNew 等带压缩能力的 GC。堆内存规整,已用/空闲区域泾渭分明;JVM 只需移动一个指针,即可快速切出所需空间。
- 空闲列表(Free List):适用于 CMS 等不压缩 GC。堆内存碎片化,JVM 维护一张可用块列表,遍历查找足够大的连续空间,再更新列表记录。
- TLAB 加速并发:默认开启。每个线程在 Eden 区预分配一块私有缓冲区(Thread Local Allocation Buffer),对象优先在 TLAB 内分配,几乎无锁;TLAB 耗尽时才同步竞争 Eden 公共区,靠 CAS 原子操作保证安全性。
分配后立即完成基础初始化
内存划出后,JVM 不等待构造逻辑,立刻执行两步关键初始化:
- 零值初始化:将实例字段所在内存(不含对象头)全部置为默认值——int 变 0、boolean 变 false、引用类型变 null。这一步确保字段即使未显式赋值,也能安全读取,不暴露随机内存值。
- 设置对象头:填充 Mark Word(含哈希码占位、GC 年龄、锁标志位等)和 Klass Pointer(指向方法区中该类的元数据)。至此,对象具备身份识别、类型反射、锁管理等运行时能力。
最后才执行程序员定义的逻辑
上述底层结构就绪后,JVM 才调用
- 按代码顺序执行字段显式赋值(如 private int x = 10;);
- 执行构造函数体内的逻辑(包括对父类构造器的调用);
- 完成业务层面的状态初始化。
此时对象才真正“活”起来,栈中引用变量也正式指向堆中这块已初始化完毕的内存区域。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











