Java对象的创建
一个普通Java对象的创建过程如下:
虚拟机在遇到new指令时,先检查常量池中是否可以定位到符号引用,检查类是否已被加载、解析和初始化。如果没有,则进行类加载处理。
加载完后,分配内存,如果内存区域规整,一边是被使用过的内存,一边是空闲内存,中间使用一个指针做分界,那这种分配内存方式叫指针碰撞。如果内存不是规整的,已使用和空闲交织在一起,那虚拟机就必须维护一个列表(Free List)。Java堆是否规整取决于垃圾回收器是否具有空间压缩整理功能。
分配内存还需要考虑的一个问题是,并发分配,虚拟机使用的方案是CAS加锁,或者使用Tread Local Allocation Buffer(本地线程分配缓存)--分配内存时,先在本地线程缓存中分配,只有本地线程缓存用完了,分配新的缓存区时才使用同步锁定。
内存分配完成后,虚拟机对内存空间都初始化为零(不包含对象头),如果使用了TLAB,这部也可以提前到TLAB分配时进行。接下来,Java虚拟机对对象头进行设置,比如设置偏向锁,设置元数据信息、对象的GC分代信息等。
在这些工作完成后,从虚拟机的角度看,对象已经产生了。但从Java程序来看,对象创建刚刚开始,构造函数还没执行。一般来说new指令之后会接着执行()方法,按程序员的意图初始化对象。这样才算对象创建完成。