在这里插入图片描述

  1. 加载检查: 首先虚拟机在遇到一条new指令的时候,会去检查这个指令的参数在常量池中是否可以定位到这个类的符号引用,并且检查该类是否被 加载、解析、初始化 过,如果没有就执行类的加载过程。
  2. 分配内存: 加载检查完就会为新生对象分配内存。分配内存的方式有两种:1️⃣指针碰撞 2️⃣空闲列表(选择哪一种内存分配方式取决于堆内存是否完整,而堆内存是否完整又取决于用了哪一种GC算法)
    • 指针碰撞的分配方式适用于内存规整的情况下,即GC算法采用了标记-清除-压缩算法,或者复制算法,因为在内存规整的情况下,已用内存和未用内存之前有个分界指针,分配内存时,只需要将指针往没有分配的区域移动内存大小的位置即可。
    • 空闲列表的分配方式适用于内存未规整的情况下,及GC算法采用了标记-清除算法,采用这种算法,会使得堆内存中有大量的内存碎片,在分配内存时,只需要找到一个大小适宜的内存进行分配即可。
    • 内存分配并发问题: 两种方式:1️⃣CAS+失败重试​(​假设没有冲突,如果发生冲突失败的话就重试直到成功)2️⃣TLAB(先在Eden区分配一块内存,当对象大于TLAB剩余的内存时,在采用CAS进行内存分配)
  3. 初始化零值: 内存分配完虚拟机就需要将分配到的内存空间都初始化为零(不包括对象头),这一步保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使⽤。
  4. 设置对象头: 初始化零值完成之后,虚拟机要对对象进⾏必要的设置,例如这个对象是那个类的实例、如何才能找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 这些信息存放在对象头中
  5. 执行Init方法: 虚拟机的角度对象已经产生了,但是从Java程序的角度来看,对象的方法还没有执行,所有字段都还为零,所以new完还需要执行方法方法才算将对象完全生产出来。
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐