1.对象创建(普通对象,除数组和Class对象)
- 当JVM遇到一条字节码new指令时,先检查是否是常量池中的类的符号引用或者是否类被加载、解析、初始化过。
- 若没有,则执行相应的类加载过程。
- 类加载检查通过后,vm将为新生的对象分配内存(从Java堆中划分出一块确定大小的内存)。
- 内存分配完成之后,vm将分配到的内存空间(不包括对象头)都初始化为零值。
- vm对对象进行必要的设置。
- 执行字节码文件中的<init()>方法
2.对象的内存布局
对象在堆内存中的存储布局分为三个部分:对象头、实例数据、对齐填充。
对象头
HotSpot虚拟机对象的对象头包含两类信息。
一类是用于存储对象自身的运行时数据。
另外一类是类型指针,对象指向它的类型元数据的指针。
实例数据
实例对象是对象真正存储的有效信息。即代码里所定义的各类型的字段内容,无论是从父类中继承的,还是子类自己定义的,都会记录起来。这部分的存储顺序会受到vm的分配策略参数-XX:FieldAllocationStyle参数和字段在Java源码中的定义顺序影响。
对齐填充
对齐填充并不是必然存在的,它只起到占位符的作用。
如果对象实例数据没有对齐,则通过对齐填充来补齐。
3.对象的访问
线程访问对象时,会创建一个栈帧,栈帧中包括局部变量表、操作数栈、方法返回地址、动态链接、reference指针等。
句柄访问
reference指针(句柄池指针)中存储对象的句柄地址,句柄中存储了对象实例数据地址和类型数据的地址。
直接指针访问(HotSpot常用)
reference指针(直接对象指针)中存储的直接就是对象地址。