-
对象的创建开始:
虚拟机遇到new 关键字的时候,首先去常量池中寻找有没有这个类的符号引用,并且检查该引用的类是否已经被加载,解析,和初始化过,如果没有则会先执行该类的加载过程, 在通过检查后,虚拟机为该新生对象分配内存。
-
分配内存:
为对象分配内存有俩种方式:
一种分配方式是“指针碰撞",在内存规整的时候,已使用的内存在一侧,未使用的内存在一侧时,中间为指示器指针,这个时候的内存分配就是把指示器指针向未使用的区域移动至创建的对象大小相等的距离。
另一种分配方式是“空闲列表”,当内存不规整时,虚拟机必须在不连续的内存空间寻找一块适合对象大小的内存区域,并使用一个列表去维护创建的每一个区域,并更新列表上的记录。
选择那种分配方式是由堆内存是否规整决定,又由所采用的gc是否带有压缩整理功能决定。
当面临并发时时,有可能存在,虚拟机给对象A分配内存时指针还未来得及改变,这个时候同时又有B对象使用指针来分配内存解决这个问题的两种式:
一种是对分配内存空间的操作进行同步处理 ,虚拟机采用的CAS 和失败重试的方式保证更新操作的原子性,另一种是把内存分配的动作按照线程划分在不同的空间进行,即每一个线程都在java堆中预先分配一小块内存。又称本地线程分配缓冲(Thread Local Allocation Buffer,简称TLAB)。 TLAB用完时分配新的TLAB 时需要同步锁定操作。虚拟机设置使用TLAB,可以通过-XX:+/UseTLAB参数设定。
-
初始化对象内存空间:
内存分配完成之后,虚拟机对该对象分到的内存空间初始化为零值(除了对象头),如果使用了TLAB ,这一工作也可以提前至TLAB分配时进行。 初始化零值这一步也是为什么对象刚创建就可以使用的原因。
-
对象设置:
虚拟机对对象进行设置,比如对象是那个类的实例,对象的哈希值,gc分带年龄等,这些信息都存在对象的头之中。之后就是执行<init>方法,到此类创建结束。
java对象的创建过程
《深入理解JAVA虚拟机》