当前位置: 首页 > news >正文

大白话读懂java对象创建的过程

1. java对象创建流程(大白话版)

咱们java对象被创建的过程大致如下,即:

在 JVM 中对象的创建,从⼀个 new 指令开始:
  1. 首先检查这个指令的参数是否能在常量池中定位到⼀个类的符号引用
  2. 检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就先执行相应的类加载过程
  3. 类加载检查通过后,接下来虚拟机将为新生对象分配内存
  4. 内存分配完成之后,虚拟机将分配到的内存空间(但不包括对象头)都初始化为零值。
  5. 接下来设置对象头,请求头⾥包含了对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的 GC 分代年龄等信息。

没听懂?没关系,咱们来看看下面这个例子:

想象你在秋招时一路过关斩将,现在终于准备入职了,这时候会有以下流程:

  1. 背景调查 → 检查类是否已加载(HR查你的学历)
  2. 分配工位 → 分配内存(给你分一个工位)
  3. 初始化设备 → 内存清零(工位电脑装好系统)
  4. 贴工牌 → 设置对象头(给你发工牌和权限)
  5. 入职培训 → 执行构造函数(教你公司规则)

    这个入职的流程就跟咱们java对象创建的过程差不多,下面咱们来分步骤一一详解。

    2. 分步骤详解

    Step 1:类加载检查

    new指令触发时,JVM会问:"这个类合法吗?"

    这时候会检查常量池中的符号引用,触发类加载机制加载 → 验证 → 准备 → 解析 → 初始化


    Step 2:分配内存

    • 方式1:指针碰撞(内存规整时)
    • 方式2:空闲列表(内存碎片化时)

    通过CAS + 失败重试保证线程安全,可能使用TLAB(线程私有分配缓冲区)

    就好像工位分配有两种策略:连续工区直接划一块(指针碰撞),或从碎片工位里拼凑(空闲列表)。

    指针碰撞:假设 Java 堆中内存是 绝对规整 的,所有被使用过的内存都被放在⼀边,空闲的内存被
    放在另⼀边,中间放着⼀个指针作为分界点的指针,那所分配内存就仅仅是把那个指针向空闲空
    间⽅向挪动⼀段与对象大小相等(这里假设是两块内存大小单位)的距离。

    空闲列表:如果 Java 堆中的内存并 不是规整的 ,已被使用的内存和空闲的内存相互交错在⼀起,
    那就没有办法简单地进行指针碰撞了,虚拟机这时候就必须维护⼀个列表,记录上哪些内存块是可用的, 在分配的时候从列表中找到⼀块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”。

    Step 3:内存清零

    将分配的内存初始化为零值(int→0,boolean→false,引用→null),保证对象实例字段不赋初值也能直接使用。就好比给你的工位电脑格式化,装好干净的系统。


    Step 4:设置对象头

    对象头内容:

    • Mark Word:哈希码、GC分代年龄、锁状态等
    • 类型指针:指向类元数据的指针

    对象头占12字节(64位JVM开启压缩指针时),就好像给你工牌贴上姓名、工号、部门等信息。


    Step 5:执行构造函数

    执行<init>方法(显式初始化成员变量),从子类到父类递归调用构造函数

    HR带你熟悉公司,布置你的工位(这才是你看到的new Object()的最终效果)。

          步骤                   技术细节                 比喻
    类加载检查双亲委派机制,元数据验证入职前的背景调查
    分配内存CAS + TLAB避免并发冲突抢会议室避免冲突
    内存清零零值初始化(JVM层)工位电脑格式化
    对象头设置Mark Word + 类型指针工牌信息(姓名/部门)
    构造函数执行程序员可见的初始化(Java层)布置工位(放私人物品)

    3. 代码示例

    Object obj = new Object();

    JVM背后做的事:

    1. 检查Object类是否加载 → 没加载则加载类
    2. 分配内存(假设8字节)
    3. 内存清零 → 所有字段为0/null
    4. 设置对象头(MarkWord + 类型指针指向Object.class)
    5. 调用Object的构造函数(这里是个空方法)

    4. 高频面试问题

    (1)为什么先清零再执行构造函数?
    :保证对象创建时字段一定有初始值(避免脏数据)。

    (2)内存分配如何保证线程安全?
    : CAS + 失败重试 或 TLAB(线程本地分配缓冲)。

    (3)对象头和对象体是什么关系?
    :对象头是元数据(如锁、GC信息),对象体是实例数据。

    相关文章:

  6. 织梦DedeCMS数据库表说明大全
  7. django入门教程之request和reponse【二】
  8. Windows 图形显示驱动开发-WDDM 3.0功能- 硬件翻转队列(六)
  9. 联想拯救者触摸板会每次开机都自动关闭、联想笔记本触摸板关闭、笔记本电脑触摸板自动关闭的解决方法
  10. 演员马晓琳正式加入创星演员出道计划,开启演艺事业新篇章
  11. 基于YOLOv8与ByteTrack的车辆行人多目标检测与追踪系统
  12. @maptalks/gl-layers中的VectorTileLayer的setStyle属性的全部line配置
  13. 群体智能优化算法-模拟退火优化算法(Simulated Annealing, SA,含Matlab源代码)
  14. 前端Tailwind CSS面试题及参考答案
  15. 实时时钟芯片HYM1381的使用(51单片机)
  16. 在K8S中挂载 Secret 到 Pod
  17. 【C#知识点详解】ExcelDataReader介绍
  18. day3 微机运算基础
  19. 【LINUX操作系统】 动静态库的链接原理
  20. 指令系统2(Load/Store 指令)
  21. 打靶笔记:利用站点Install功能连接Kali本地数据库
  22. 传输层协议 — TCP协议与套接字
  23. Practical Data Science with SAP Machine Learning Techniques for Enterprise Data
  24. KMP-子串匹配算法-关键点理解
  25. 蓝桥杯 对联【算法赛】
  26. 出走的苏敏阿姨一路走到了戛纳,这块红毯因她而多元
  27. 80后女博士黄双燕拟提名为内蒙古盟市政府(行署)副职人选
  28. 郑钦文憾负高芙,止步WTA1000罗马站四强
  29. 国税总局上海市税务局通报:收到王某对刘某某及相关企业涉税问题举报,正依法依规办理
  30. 泰山、华海、中路等山东险企综合成本率均超100%,承保业务均亏损
  31. Offer触手可及,2025上海社会组织联合招聘专场活动正寻找发光的你