Java中new创建对象包含四步:1.类加载检查;2.堆内存分配(指针碰撞/空闲列表/TLAB);3.零值初始化与对象头设置;4.执行构造方法完成实例化。

Java 中使用 new 关键字创建对象时,不是简单地“分配一块内存”,而是一系列严格、有序的 JVM 内部动作。理解这个过程,对排查内存问题、理解类加载机制和 GC 行为都很关键。
1. 类加载检查(Class Loading Check)
JVM 首先检查 new 指令的参数是否能在常量池中定位到一个类的符号引用;然后验证该类是否已被加载、解析和初始化。若未加载,会触发类加载过程(加载 → 验证 → 准备 → 解析 → 初始化)。只有完成初始化后,才能继续下一步。
2. 内存分配(Memory Allocation)
在堆(Heap)中为新对象分配内存,具体方式取决于垃圾收集器和 JVM 参数:
- 指针碰撞(Bump the Pointer):适用于内存规整场景(如 Serial、ParNew + 整理式 GC)。JVM 维护一个“空闲内存指针”,分配时只需将指针向空闲方向移动对象所需大小。
- 空闲列表(Free List):适用于内存不规整(如 CMS、G1 在部分区域)。JVM 维护一张记录可用内存块的列表,从中查找足够大的空间并更新列表。
- TLAB(Thread Local Allocation Buffer):为避免多线程竞争堆内存分配锁,JVM 默认为每个线程在 Eden 区预分配一小块私有缓冲区。大多数小对象优先在 TLAB 中分配,失败再尝试 Eden 共享区或触发同步分配。
3. 初始化零值与设置对象头(Zeroing & Object Header Setup)
内存分配完成后,JVM 立即把该内存区域所有字节初始化为零(不包括对象头),保证实例字段即使未显式赋值也有默认值(如 int=0、boolean=false、引用=null)。
同时,JVM 为对象设置对象头(Object Header),包含两部分信息:
- Mark Word:存储哈希码、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID 等运行时数据(32/64 位平台长度不同)。
- 类型指针(Klass Pointer):指向方法区中该对象所属类的 Class 对象(用于确定类型信息),开启指针压缩时占 4 字节。
注意:此时对象已具备运行时基本结构,但字段仍为默认值,构造方法尚未执行。
4. 执行构造方法(init 方法)
JVM 调用对象对应的 init 方法(即 Java 源码中的构造器),按代码顺序:
- 执行父类构造器(隐式或显式 super())
- 对实例变量进行显式初始化(如
int x = 5;) - 执行构造器中用户编写的逻辑(如 this.x = x;)
至此,对象才真正“可用”,引用被赋给栈上的变量(如 MyClass obj = new MyClass(); 中的 obj)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











