java 对象的创建过程
- 虚拟机在遇到一个new 指令时,首先会去常量池中定位到这个类的符号引用,并且检查这个类是否已经被加载、解析和初始化过,如果没有,那必须先进行相应的类加载的过程。
- 类加载检查完成后,开始为对象分配内存
- 内存的分配方式有两种:① 指针碰撞:内存是规整的,用过的内存和空间内存用指针隔开,当需要内存时,只需要移动指针即可。② 空闲列表 :内存不是规整的,使用的内存和空闲内存相互交错,虚拟机通过维护一个列表来记录那些内存是可用的,分配内存时从列表中找到相应大小的内存即可。采用哪种分配方式取决于垃圾收集器是否带有压缩整理的功能。一般来说,新生代的垃圾搜集算法是复制-清除,分配内存的方式为指针碰撞;老年代的垃圾收集器采用的算法是标记-清除,分配内存的方式是空闲列表(当否老年代中找不到连续的大空间分配内存时就会发生Full GC)。
- 分配内存时需要考虑线程安全问题(对象A分配内存时,指针还没来得及修改,这时对象B又使用的原来的指针)。有两种解决方案:① 同步处理:虚拟机采用cas加上失败重试的方式保证分配内存的原子性。② 在java堆中,为每个线程预先分配一小块内存,成为本地线程分配缓冲(Thread Local Allocation Buffer TLAB),只有TLAB用完需要分配新的TLAB时,才需要同步(是否使用TLAB,可以通过参数控制)。
- 内存分配完成后,虚拟机将分配到的内存空间都赋值为0,这个操作保证了对象在不赋值的时候也可以直接使用。
- 设置对象头中的信息(哪个类的实例,hash码,分代年龄,是否启用偏向锁)。
- 对于虚拟机来说,一个对象就创建完成了。对于程序员来说,还需要进行初始化操作。