1、类加载检查
这步主要是JVM检测到new指令时,先去检查这个指令的参数能否在常量池中定位到一个类符号引用,并检查该符号引用代表的类是否被加载、解析和初始化过。如果没有执行类加载过程。
- [类加载过程???]
2、分配内存
加载完类之后对象所需内存大小即可确定,为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。
- 如何划分内存
指针碰撞:java内存非常规整,用过的内存放在一边,未用过内存放在一边,中间放着一个指针作为分界点,分配内存仅仅是把那个指针向空闲那边挪动一段与对象大小相等的距离;
空闲列表:Java内存不规整,使用过与未使用过的内存相互交错,虚拟机需要维护一个列表,记录那些内存可用,分配的好时候从列表上找到一块足够大的空间分给对象,并更新列表。
- 在并发情况下,正在给对象A分配内存,指针没有来得及修改,对象B又同时使用原来指针分配内存
CAS:虚拟机采用CAS配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。
本地线程分配缓冲:把内存分配的动作按照线程划分在不同空间中进行
3、初始化
内存分配完成,虚拟机需要将分配到的内存空间初始化为零值,如何使用TLAB(本地线程分配缓冲),这一工作过程也可以提前到TLAB分配时进行。
4、设置对象头
在HotSpot虚拟机中,对象内存布局分对象头、示例数据、对齐填充。对象头包括两部分数据:1、存储运行的数据:哈希码、GC分代年龄、锁状态标志;2、类型指针:虚拟机通过这个指针确定对象时哪个类实例
5、执行构造函数init方法
对象按照程序员意愿进行初始化。就是为属性赋值,执行构造方法。