1.类加载检查
当虚拟机接收到new指令后,先去字符串常量池检查这个参数的类的符合引用定位是否存在,并检查类的符号引用是否已经加载,解析和初始化,如果没有则先进行类的加载。
2.对象内存分配
类加载完成后,便可以确定对象的内存大小,虚拟机会给对象划分指定大小的堆内存。划分的方式有两种:1.指针碰撞,2.空闲列表,使用那种方式分配内存取决于堆内存是否规整,堆内存是否规则又取决于的垃圾回收器是否有压缩整理功能决定。∗∗1.指正碰撞∗∗虚拟机将使用过的内存放在一边,没使用过的内存放到另外一边,中间有一个指针箭头指向未使用过的内存,当有对象需要分配内存适合,指针会向未使用的内存移动指定的对象内存大小∗∗2.空闲列表∗∗虚拟机会将未使用过的内存碎片,使用一个列表维护起来,当需要分配内存的时候,虚拟机会在空闲列表里找到指定大小的内存分配给对象,并更新空闲列表。
3.初始化值零值
内存分配完后,虚拟机将对内存空间进行初始化。这一步保证java代码中对象即使不设初始化值也能直接使用,程序可以访问到对象字段对应类型的零值。
4.设置对象头
设置为初始值后,虚拟机需要对对象进行必要的设置,例如需要保存类的hasCode,类的元数据信息,对象的GC年代信息等等。这些信息都保存到对象头里。
5.执行init方法
完成了一系列的步骤后,从虚拟机角度来看对象已经是创建完成了,从程序的角度来看,对象才刚刚开始创建,还需要执行init方法,所有字段值都还是零,虚拟机创建完对象后,紧接着执行init方法,按照程序员的意图去初始化对象,这样一个对象才算是真正的完成。