JVM创建一个对象时需要经过以下几个步骤
类加载检查
每当程序员使用new操作符创建一个对象时,类加载器都会从常量池中寻找该对象的符号引用,如果找到,则根据该引用查询该类是否已被加载,否则进行接下来的类加载操作,在此过程中,类所需内存大小也被确定下来
分配内存
JVM根据在类加载检查中确定的内存大小,在堆中为类开辟一段空间,分配的方式有指针碰撞、空闲列表两种方式,若JVM的垃圾回收器(GC)使用了标记-整理的算法,即有值的内存往左侧移动,使得内存规整,则采用指针碰撞分配。若GC使用的是标记-清除算法,定期清除堆中无效的内存空间,则使用空闲列表,在堆中寻找一块内存合适的空间分配内存。
JVM使用cas+失败重试的方式保证并发处理时,创建对象的线程安全,cas为乐观锁的一种实现,即不加锁,默认在执行操作时不会发生冲突。若发生了冲突则进行失败重试,直到完成操作为止。
每当线程创建时,首先给线程分配一块自己的内存,分配内存首先在此分配,当线程内的内存空间不足以为对象分配内存时,再采用cas+失败重试的方式分配。
初始化零值
内存空间分配完毕后,对内存中的值都进行初始化,如整型的值为0,引用类型为null,这使得类实例可不经初始化直接使用
设置对象头
初始化零值过程并不包括初始化对象头,这一步是针对JVM虚拟机的,如设置对象的hashCode,GC分代年龄,类的索引信息等。
init
执行程序员自己定义的初始化对象信息的内容,如执行构造函数中的代码。