2、Java对象的创建过程

1、检查是否被加载

虚拟机在遇见一条new指令的时候,首先去检查该指令的参数是否能够在常量池中定位到一个类的符号引用以及该符号的类是否已经被加载、解析和初始化过。如果没有加载类那么加载类,在加载类的时候将会执行clinit()方法对静态变量和静态代码块进行初始化。

2、内存分配

一个类的内存在被加载之后,就能够确定该对象所需要的内存大小。前面说过,Java的堆是用于存放对象实例的,因此该内存的操作主要是在堆内存上面。
内存分配有两种方式,第一种是指针碰撞,这种方式适合于Java堆中内存很规整的情况。在这种情况下,内存是绝对规整的,所有用过的内存都放在一边,空闲的在另一边,中间由一个指针作为分界点的指示器。分配内存就是将指针向空闲空间移动一段和对象大小相等的距离。第二种方式是空闲列表,这种方式中Java堆的内存是不规整的,JVM维护一个看列表用于记录那些内存块是可用的,在分配的时候从列表中寻找一块足够大的空间划分给对象实例并更新列表上的记录。
在内存分配的时候要考虑一个线程安全性的问题。虚拟机使用的方法为CAS来保证操作的原子性。同时还有一种TLAB(本地线程分配缓存)方法分配空间,这种方法会将内存分配按照线程在不同的空间中进行。哪个线程需要分配内存,就在那个进程的TLAB上分配。
在内存分配完毕之后就会将分配到的内存空间除对象头之外都初始化为零值。

3、对象头的设置

在该阶段将会设置对象头中的数据。对象头的数据中包括两部分信息,第一部分为存储对象自身的运行数据,比如HashCode、GC分代年龄、锁状态标志、线程持有锁、偏向线程ID和偏向时间戳等。第二部分为类型指针,类型指针指向他的类元数据的指针,通过改指针来确定该对象是哪一个类的实例。
如果该对象为数组,则对象头中还存在距离数组长度的数据。

4、执行方法

在这个阶段执行方法。是instance实例的构造器,对非静态变量解析初始化。

你可能感兴趣的:(2、Java对象的创建过程)