对象的创建关注以下几个问题:
1、为创建的对象分配内存空间有两种方式:
指针碰撞:
即规整的划分空间,内存空间中用过的放一边,没用过的放另外一边。需要分配时,指针向空闲空间那边挪动一段与对象大小相等的距离。
空闲列表:
已用和未用空间相互交错,虚拟机需要维护一个列表,记录哪些内存是可以用的,在分配的时候找到一块足够大的给创建的对象实例,并更新列表记录。
2、对象创建在并发情况下不是线程安全的。此时有两种解决方案:
-对分配空间的行为进行同步,采用cas配上失败重试的方法保证操作的原子性。
-为每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)。哪个线程需要分配,就在自己的TLAB上进行。当TLAB空间不足时,再采用同步的方式进行。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。
3、虚拟机对对象设置对象头信息。如这个对象时哪个类的实例、对象的哈希码、对象的GC分代年龄等等。
在虚拟机的角度来看,一个新的对象已经创建完成了。但是从Java程序的角度来看,这个对象的创建才刚刚开始,因为init方法还没有执行,所有字段值还是零。所以new指令之后会执行init方法,把对象按照程序员的意愿进行初始化。