一、创建对象的完整过程
1. 类加载检查
JVM 遇到
new指令时,首先去检查这个类User是否已经被加载、解析和初始化过。如果没有,就先执行 类加载过程 (加载
.class文件到方法区/元空间、创建 Class 对象等)。【这个过程就是加载、验证、准备、解析、初始化】
2. 分配内存
JVM 在 堆(Heap) 中为新对象分配内存。
分配方式可能是:
指针碰撞(bump-the-pointer):堆内存规整时,用一个指针往后挪就能完成分配。
空闲列表(free-list):堆内存不规整时,需要维护可用内存块列表来找到一块合适的空间。
3. 内存初始化(零值初始化)
对分配到的内存空间进行 零值初始化,保证对象的实例字段有默认值。
比如:
int→0,Object→null,boolean→false。这样保证 Java 程序不读到脏数据。
4. 设置对象头
JVM 会在对象头中写入信息:
哈希码(可能延迟计算)
GC 分代年龄
类的元数据指针(指向方法区中的 Class 对象)
锁信息(偏向锁/轻量级锁/重量级锁)
5. 执行
<init>方法(构造函数)
new指令会执行对象的构造函数,真正完成对象的初始化。先执行父类构造方法,再执行子类构造方法。
至此,字段会被赋予程序员写的初始化值(而不是零值)。
6. 返回对象引用
new指令执行完毕后,返回对象在堆中的引用地址。
user变量存放的是这个对象的 引用(指针),而不是对象本身。
二、简化流程图
new -> 类加载检查 -> 分配内存 -> 零值初始化 -> 设置对象头 -> 调用构造函数 <init> -> 返回引用
三、额外说明
栈 vs 堆
对象本身存放在堆里;
引用变量(比如
user)在栈帧的局部变量表里,存放堆中对象的地址。优化:TLAB(Thread Local Allocation Buffer)
多线程环境下,为了避免内存分配加锁,JVM 会给每个线程分配一小块内存(TLAB)。
绝大多数对象都能在 TLAB 上直接分配,效率非常高。
逃逸分析 & 栈上分配
JIT 优化时,如果发现对象不会逃出方法范围,可以直接在 栈 上分配,而不是堆。
这样方法执行完对象就回收,不需要 GC。
✅ 总结一句话:
Java 创建对象的过程是:
类加载检查 → 堆内存分配 → 零值初始化 → 设置对象头 → 调用构造函数 → 返回引用。
面试tips--JVM(2)--对象创建的过程
你我约定有三2025-08-29 14:35
相关推荐
罗超驿10 分钟前
18.事务的隔离性和隔离级别:MySQL面试高频考点全解析做人求其滴38 分钟前
面试经典 150 题 380 274小江的记录本1 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)小卡不对头1 小时前
软考中级通过率怎样?软考中级哪个通过率高ricardo19732 小时前
# Tree Shaking 深度解析:为什么你的代码没被摇掉?小江的记录本2 小时前
【Java基础】反射与注解:核心原理、自定义注解、注解解析方式(附《思维导图》+《面试高频考点清单》)罗超驿3 小时前
19.告别复杂SQL!用MySQL视图把逻辑拆成“变量”式操作中小企业实战军师刘孙亮5 小时前
家居建材营销新趋势:数字化、体验式与可持续方向-佛山鼎策创局破局增长咨询有限公司凯瑟琳.奥古斯特5 小时前
传输层核心功能解析jiayong236 小时前
前端面试题库 - 浏览器与网络篇