Java虚拟机中对象(仅限于普通的Java对象,不包括数组和Class对象)的创建流程如下:
1.虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。如果有,那必须先执行相应的类加载过程。
2.类加载检查通过后,虚拟机将为新生对象分配内存,为对象分配空间也就是把一块确定大小的内存从Java堆中划分出来。
假设Java堆中的内存是规整的,也就是用过的内存在一边,空闲的内存在另一边,中间放着一个指针作为分界点的指示器,那么分配内存也就是把那个指针向空闲内存那边挪动一段与对象大小相等的距离,这种分配方式叫“指针碰撞”;
但如果Java堆中的内存不是规整的,即已使用的内存和空闲的内存相互交错,这时就无法使用指针碰撞了,此时虚拟机就需要维护一个列表,记录那些内存是可用的,在分配内存的时候从列表中找到一块足够大的空间分配给对象,并更新列表,这种分配方式叫“空闲列表”。
选择哪种方式是由Java堆是否规整决定的。
3.内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(可以使用本地线程分配缓冲(TLAB));
4.虚拟机要对对象进行必要的设置,例如对象是哪个类的实例、对象的哈希码、GC分代年龄等信息,这些信息存放在对象的对象头之中。
5.执行new指令之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化,这样一个可用的对象才算完全产生出来。
注:参考文献:《深入理解Java虚拟机:JVM高级特性与最佳实践》——周志明 著