对象的创建
类对象的加载
检查符号引用代表的类是否已被加载、解析和初始化,如果没有则执行类加载过程。
为新生对象分配内存
对象所需内存的大小在类加载完成后便可完全确定。为对象分配空间的任务实际等同于把一块确定大小的内存块从Java堆中划分出来。创建对象的时候,根据Java堆是否规整,采用“指针碰撞”(不规整)、或“空闲列表”(规整)。根据GC收集器类型而定。虚拟机也会在对象的对象头中,设置对象的信息。
【如果在并发情况下,地址是可能会出现问题的,这个时候采用CAS乐观锁、或者本地线程分配缓冲TLB(每个线程在堆中分配缓存,分配新的缓存区才需要同步锁定)。】
对象初始化
new指令之后执行
对象的内存布局
HotSpot虚拟机对象的头对象包括两类:
1)用于存储对象自身运行时的数据,包括哈希码、GC分代年龄等
2)类型指针,对象指向它的类型元数据的指针,通过该指针确定该对象是哪个类的实例
3)对象真正存储的有效信息,即在程序代码里所定义的各种类型的字段内容。
4)对齐补充,起着占位符的作用。
对象的访问定位
程序通过栈上的引用数据来操作堆上的具体对象。主流的访问方式包括使用句柄和直接指针的方式。
1)句柄访问:Java堆中划分一块内存出来作为句柄池,栈中存储的是对象的句柄地址。好处是引用中存储的是稳定的句柄地址,在对象被移动时只会改变实例数据的指针(栈的引用不变)
2)直接指针访问:Java堆中的对象内存布局,引用中存储的直接就是对象的地址。(减少了一次指针定位的开销,对象访问频繁,积少成多也是成本)。