logo头像
Snippet 博客主题

【玩转jvm系列】02.对象探秘

注意:本文描述的内容是基于HotSpot虚拟机。

对象的创建

对象创建流程图

image

对象创建流程

  1. 虚拟机遇到一条new指令
  2. 检查该指令参数在常量池中能否定位到对应类的符号引用
  3. 检查该类是否被加载、解析和初始化,如果没有必须先执行加载过程
  4. 虚拟机为新生对象分配内存
  5. 虚拟机将分配到的内存空间都初始化为零值
  6. 虚拟机对对象进行必要的设置(设置对象头)
  7. 执行方法,把对象按照程序员的意愿进行初始化

    对象的内存布局

    在HotSpot虚拟机中,对象在内存中存储的布局可以分为三个区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

image

  • 对象头包含两部分
    • 第一部分存储对象自身的运行时数据,如HashCode、GC分代年龄、线程持有的锁等。
    • 第二部分是类型指针,即对象指向它的类元数据的指针。如果对象是数组,对象头必须又一块用于记录数组长度的数据。
  • 实例数部分(对象Body部分)
    • 存储代码中所定义的各种类型的字段内容。
    • 无论子父类,都需要记录下路。
  • 对齐填充
    • 对齐填充不是必然存在的,也没有特别含义,仅仅起占位符的作用。
    • 对象的大小必须是8字节的整数倍,不足就通过对齐填充补充。

      对象的访问定位

      目前主流的访问方式有使用句柄直接指针两种。

      使用句柄方式

      image

使用句柄访问的最大好处就是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不需要修改。

直接指针访问方式

image

直接指针访问的方式的最大好处就是速度更快,它节省了一次指针定位的时间开销,由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是一项非常可观的执行成本。

小结

虚拟机Sun HotSpot,它使用的是第二种方式进行对象访问的,但从整个软件开发的范围看,各种语言和框架使用句柄来访问的情况也十分常见。

微信打赏

赞赏是不耍流氓的鼓励