深入理解JAVA虚拟机(二)详解JVM对象的创建过程

在JAVA的世界里,对象无处不在,程序员每天大部分工作都是在new对象,然后调用对象的方法去完成一些功能,下面详解在JVM中(HotSpot)对象的创建过程:

先看一张创建流程图:

对象创建流程图

大致有以下几个步骤:

  1. 类加载检查过程:

    ​ JVM接到new指令后,会先在常量池中检查是否存在类的“符号引用”,再检查是否被加载、解析、初始化。如果没被加载过,执行初始化过程。

    关于符号引用:jvm内存区域划分中,有一块共享内存区叫方法区,用于存储虚拟机加载的类信息、常量、静态变量和即时编译后的代码。“符号引用”是类编译成class文件时,在class文件的常量池中存放的一个能找到该类的一个字符串,在JVM加载后,存放于方法区的运行时常量池。

  2. 在堆中给对象分配内存

    ​ 内存的分配方式有两种:“指针碰撞”和“空闲列表”,这个取决于堆中的内存是否规整。如果堆中的内存绝对规整,所有用过的内存放一边,空闲的内存放另一边,中间放一个指针作为分界点的指示器,分配内存时,只需要将指针往空闲那边挪动一段与需要分配内存大小相等的距离即可,这种分配方式就叫“指针碰撞”;如果Java堆不是规整的,则需要维护一个列表,记录哪些内存可用,哪些内存已被使用,分配时从未使用的内存列表中找到一块足够大的空间分配给对象,再更新该内存为已使用,这种分配方式叫“空闲列表”。

  3. 初始化内存空间为零值

    ​ 这一步操作保证了对象实例字段在JAVA代码中可以不赋初始化值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值(byte/short/int : 0 ,boolean : false,long : 0L,float : 0.0f,double : 0.0d,char : ‘/uoooo’(null),对象引用 : null)。

  4. 设置对象头

    ​ 4.1 Mark Word :对象自身的运行时数据,如HashCode、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。

    ​ 4.2 类型指针:指向类元数据的指针,JVM通过类型指针,确定当前对象属于哪个类(不是所有的JVM都在对象头中设置类型指针数据,有的是保存在句柄池中)。

  5. 执行对象的init()方法初始化对象,完成对象的创建。

坚持原创技术分享,您的支持将鼓励我继续创作!
分享