Java虚拟机 对象创建流程、初始化流程

本文详细探讨了Java虚拟机中对象的创建流程,包括类加载、内存布局、对象头、实例数据和对齐填充。同时,解析了Mark Word的结构,以及对象初始化的顺序。此外,还讲解了对象的访问定位方式,如句柄和直接指针。通过理解这些细节,有助于深入理解JVM的工作原理。
摘要由CSDN通过智能技术生成

前言

梳理对象创建流程和初始化流程

Java虚拟机运行时数据区

对象创建流程

对象创建

  1. new指令时,定位该指令的参数在常量池中的符号引用
    • 遇到new、getstatic、putstatic、invokestatic这4条字节码指令时,
    • 使用java.lang.reflect包的方法对类进行反射调用时。
    • 当初始化一个类时,发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
    • 当虚拟机启动时,虚拟机会先初始化包含main()方法的主类。
    • 被动引用不会触发类的初始化:
      • 子类引用父类的静态字段,不会导致子类初始化。
      • 通过数组定义来引用类,不会触发此类的初始化。new ChildClass[0]。
      • 引用类中的常量,不会触发此类的初始化。
  2. 如果没有,则进行类的加载、连接和初始化。
  3. 虚拟机为新生对象分配内存
  4. 将分配到的内存空间都初始化为零值,不包括对象头,并初始化对象头(哈希码、gc年龄等)
  5. 调用对象<init>方法

另外new对象操作不是原子性的,

  1. 给Singleton实例分配内存
  2. 调用Singleton()构造函数,进行初始化
  3. 将mSingle对象指向分配的内存空间
    因为按照内存模型中线程工作内存回写到主内存时2、3的步骤是不确定的,当3在前面发生时,会引发DCL(Double check Lock)失效问题,可以使用volatile禁止指令重排,保证按顺序执行,直接从主内存读写,就不会出错了。

1. 类加载流程

深入理解Java虚拟机 第七章 虚拟机类加载时机与过程

2. 对象的内存布局

对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。

1. 对象头

Hotspot虚拟机的对象头主要包括两部分数据:Mark Word(标记字段)、Klass Pointer(类型指针),数组会多1字宽(32位: 4字节)来存储数组长度。

  • Mark Word用于存储对象自身的运行时数据,它是实现轻量级锁和偏向锁的关键。
  • Klass Point是对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例;

2. 实例数据

该部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容,包括父类继承下来的和子类中定义的。

3. 对齐填充

该部分不是必须的,某些虚拟机要求对象的起始地址必须是8字节的整数倍,即对象大小必须是8字节的整数倍,所以不足时就需要对齐。

4. Mark Word详解

JVM中对象头的方式有以下两种(以32位JVM为例):

// 普通对象
|--------------------------------------------------
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baiiu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值