这里说的对象创建过程,仅仅指的是普通的对象。创建对象,仅仅只是一个new关键字。
- 查找是否有符号引用:当虚拟机接收到一个new 指令时,会去常量池里面去找有没有这样到一个符号引用。
- 是否被加载:判断这个符号引用是否已经被加载链接初始化。如果没有,要先执行类的加载过程。
- 分配内存:分配内存的时候需要注意线程安全问题,为了避免同一块内存地址被分配给对象的问题。
- 主要有两种方式来避免
- CAS:采用cas乐观锁失败重试的方式来保证原子性
- TLAB:TLAB就是内存分配发生在对应的线程内,发生在不同的物理空间上。每个线程会预先在内存堆中划分好一部分的内存空间。称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB).分配内存时就在预先分配的内存中进行。当TLAB内存用完,需要重新划分TLAB时,才需要同步锁。
- 分配内存的策略主要有以下两种
- 空闲列表:空闲列表主要适用于内存空间不规整的场景。也是内存回收策略是标记-清除的算法场景。内存里面需要维护一个列表,用于记录哪些内存被使用,哪些内存是空闲的。分配内存的时候需要在列表中查找一个相等大小的内存区域。并修改列表状态。
- 指针碰撞:指针碰撞主要适用于内存空间比较规整的场景。也就是说内存回收策略里面使用了标记-整理算法的场景。已经使用的内存放在一边,未使用的内存放在另外一边。中间放着一个指针作为分界点的指示器。分配内存时,只需要移动指针,移动一段和对象大小相等的距离。
- 主要有两种方式来避免
- 初始化对象头信息:包括元数据,分代回收信息,对象哈希码。
- 执行init 构造函数:执行new 指令后,会执行构造函数,按照程序做初始化。