🌱 当你在 Java 中写下:
MyClass obj = new MyClass();
✅ JVM 在背后做了这些事:
1️⃣ 类加载检查
- 确保
MyClass
已被加载、链接、初始化。 - 如果没有,先执行类加载器流程:
- 加载
.class
文件 - 验证字节码
- 准备静态字段
- 执行
<clinit>
静态代码块(如果有)
2️⃣ 分配内存
- JVM 在堆上为这个对象分配内存空间,足够容纳所有字段。
- 有两种策略:
3️⃣ 内存初始化为零值
int
-> 0
boolean
-> false
- 引用类型 ->
null
- 注意:不会执行你写的构造方法里的赋值!
4️⃣ 设置对象头
- 对象哈希码(可能延迟生成)
- GC 标志(如是否为可达对象)
- 类元数据指针(指向类结构,用于虚方法分发等)
5️⃣ 执行构造方法 <init>
- JVM 调用你的构造函数
MyClass()
,对对象字段进行初始化。 - 此时可以给字段赋你自定义的值。
- 注意:
super()
会先被调用,初始化父类部分。
6️⃣ 返回对象引用
- 最后把这块堆内存地址(即对象引用)赋值给变量
obj
。
🧠 图解理解:
new MyClass();
↓
[类加载器] 检查类是否已加载
↓
[堆内存分配] 创建空壳对象
↓
[初始化字段] 全设为默认值
↓
[设置对象头] 指向类元数据
↓
[调用构造函数] 执行你的初始化逻辑
↓
返回 obj 引用
🚀 小补充:JVM 优化点
- 逃逸分析:如果对象不会逃出方法,JVM 甚至可能优化成栈上分配。
- TLAB(线程本地分配缓冲):在多线程中加快对象分配速度。
- GC 标记:设置对象头以便 GC 追踪对象生命周期。