HotSpot 虚拟机对象探秘

2019-07-31  本文已影响0人  来醉一场

一、对象的创建过程

当虚拟机遇到一条new 指令时:

  1. 检查
  1. 分配内存
  1. 初始化零值
  1. 设置对象头
  1. 执行init 方法。

二、对象的内存布局

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

  1. 对象头(Header)

    HotSpot 虚拟机的对象头包括两部分信息:

    存储如哈希码(HashCode)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为 32bit 和 64bit,官方称为“Mark Word”.

  类型指针即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

  1. 实例数据(Instance Data)

  实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是子类中定义的,都需要记录起来。这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)的字段在 Java 源码中定义顺序的影响。HotSpot 虚拟机默认的分配策略为 longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers),从分配策略中可以看出,相同宽度的字段总是被分配到一起。在满足这个前提条件的情况下,在父类中定义的变量会出现在子类之前。如果 CompactFields 参数值为true(默认为true),那么子类之中较窄的变量也可能会插入到父类变量的空隙之中。

  1. 对齐填充(Padding)

  对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用由于 HotSpot VM 的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍。当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

三、对象的访问定位

  Java 程序需要通过栈上的 reference 数据来操作堆上的具体对象。目前主流的访问方式有使用句柄和直接指针两种。

Sun HotSpot 是使用直接指针方式进行对象访问的。

上一篇下一篇

猜你喜欢

热点阅读