对象的创建过程
一、检查
- 检查指令的参数是否能在常量池中定位到一个类的符号引用
- 检查这个符号引用代表的类是否已被加载、解析和初始化过
- 类加载检查是否符合《Java虚拟机规范》的全部约束要求
二、分配内存
1.选择分配方式。
Java堆中的内存如果是绝对规整的,将会采用“指针碰撞”的分配方式;
反之采用“空闲列表”的分配方式。
而Java堆中的内存是否规整又采用的垃圾收集器是否带有空间压缩整理的能力决定。
因此使用Serial、ParNew等带压缩整理过程的收集器时,系统采用的分配算法是指针碰撞,既简单又高校。
使用CMS这种基于清除算法的收集器时,采用比较复杂的空闲列表来分配内存
2.因为创建对象是虚拟机中非常频繁的行为,要解决线程问题。
虚拟机提供了两种解决方案:
一种是采用CAS配上失败重试的方式保证更新操作的原子性;
另一种是为每个线程在Java堆中预先分配一块内存,称为本地线程分配缓存(Thread Local Allocation Buffer, TLAB)
三、初始化
隐式初始化。
虚拟机将分配到不包括对象头在内的内存空间初始化为0,如果这分配内存时采用TLAB解决线程安全问题,那么这一步会提前至TLAB分配时顺便进行。
显示初始化。
虚拟机为对象头进行必要的设置,
例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。
从虚拟机的视角来看,一个新的对象已经产生了。执行
<init>()
方法,按照开发者的意愿对对象进行初始化,此时一个真正可用的对象才算完全被构造出来。