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

前言

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

Java虚拟机 对象创建流程、初始化流程_第1张图片

对象创建流程

Java虚拟机 对象创建流程、初始化流程_第2张图片

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

另外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为例):

// 普通对象
|--------------------------------------------

你可能感兴趣的:(dalvik/art虚拟机,多线程,java,jvm)