读书笔记《深入理解Java虚拟机》 (二)对象创建、内存布局、访问定位

对象的创建

  • 类加载检查
  1. 检查这个指令的参数是否能在常量池中定位到一个类的引用
  2. 检查这个符号引用代表的类是否已被加载、解析和初始化过, 如果没有,那必须先执行相应的类加载过程
  3. 确定对象所需内存的大小
  • 为新生对象分配内存
  • 初始化对象的字段, 大概例如 int类型的初始值0就是在这里初始化的吧
  • 对对象进行必要的设置,设置对象头信息(对象的哈希码、GC分代年龄等)
  • 执行<init>方法

对象的内存布局

  • 对象头
  1. 第一部分:储存对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁等
  2. 第二部分:类型指针,虚拟机可以通过这个指针来确定这个对象是哪个类的实例。不是必须;如果对象是一个java数组,对象头还必须记录数组长度,因为从数组的元数据中无法确定数组的大小,对象可以;然后是实例数据,无论是父类继承的,还是子类定义的,相同宽度的字段总是分配到一起
  3. 第三部分:对齐填充,不是必然存在的。对象的大小必须是8字节的倍数,当对象大小不足以对齐时,就需要通过对齐填充来对齐

对象的访问定位

  • 第一种,通过句柄访问,在java堆中划分出来一块内存作为句柄池,句柄池记录了对象实例数据、类型数据的指针,在java栈本地变量表中记录了句柄池的地址。优点:当句柄池中的指针有变化时,java栈中的地址可以不变。
  • 第二种,通过直接地址访问,优点是比句柄访问方式速度更快,节省了定位句柄池。

猜你喜欢

转载自blog.csdn.net/baitianmingdebai/article/details/84894004