1.对象的创建
通过new创建对象时,首先检查这个符号引用所代表的类是否已经被加载、解析和初始化过。如果没有,执行相应的类加载过程。
2.内存分配
对象所需要的内存空间在类加载完成后便可完全确定
2.1分配方法
1.指针碰撞;2.空闲列表
2.2选择依据
选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能而决定。在使用带compact过程(Serial、ParNew)的收集器时,采用指针碰撞; 在使用基于Mark-Sweep算法的收集器时,采用空闲列表。
2.3初始化
内存分配完成后,虚拟机需要将分配到的内存空间初始化为零值。这一步操作保证了对象的实例字段不赋初始就可以直接使用
2.4设置对象信息
2.5执行<init方法>
3.对象的内存布局
对象在内存中的存储布局可分为3部分:对象头、实例数据、对其填充
3.1对象头
对象头主要包括两部分信息:储存对象自身的运行时数据、指向它的类元数据指针
3.2实例数据
对象真正存储的有效信息(字段信息)
3.3对齐填充
对象的大小必须是8字节的整数倍,通过对齐填充来补全
4.对象的访问定位
对象创建完成后,通过虚拟机栈上的局部变量表中的reference数据来操作堆上的对象。主要访问方式有两种:句柄和直接指针。
使用句柄的好处是:reference存的是稳定的句柄地址, 对象被移动时(垃圾回收会移动对象)只会改变句柄中实例数据指针,reference本身不需要修改
直接指针的好处:减少了一次指针定位的开销。HotSpot虚拟机采用的是该种方式