1 类加载检查:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,那必须先执行相应的类加载过程。
2 是否已加载 如果没有 加载类 详情看JVM类加载过程
3分配内存:
规划划分内存的方法:
1 指针碰撞(默认)
2 空闲列表
解决并发问题的方法: 1 CAS 2 本地线程分配缓冲
4初始化 :
内存分配完成后,JVM需要将分配到的内存空间都初始化为零值(不包括对象头), 如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
5设置对象头 :
对象头组成;
Mark Word标记字段 (32 bits)
Mark Word 组成: 对象hashCode 25bits + 分代年龄 4bits (15)+ 是否偏向锁1bits + 锁标志位 2bits
klass Pointer类型指针(开启压缩 32 bits 关闭压缩 64bits)
数组长度(数组对象才有 32bits)
对象的组成: 对象头(Header) + 实例数据(Instance Data)+对齐填充(Padding)
6 执行<init>方法:执行<init>方法,对象按照程序员的意愿进行初始化。对应到语言层面上,就是为属性赋值(注意,这与上面的赋零值不同,这是由程序员赋的值),和执行构造方法。