Java 对象头

一、引言

  • java对象头很重要,synchronize、GC、HashCode、biasedLock、ObjectMonitor都是在对象头上作文章。php

  • 其实整个Java能够说是构建在oop-klass体系上的,相信从各类技术博客、书籍你们都了解很多。可是基本上都是32位虚拟机下,可能周志明大神的学习笔记太多。java

  • 本文不打算讲讲oop-klass体系(能力有限),只聊聊64位虚拟机下普通的对象头,jdk1.8.0_221,jvm参数:-XX:-UseCompressedOops,但愿对读者有所帮助。数组

二、认识oop

  • oo-klass的基石之一,先来看看oop(实际上是个oopDesc *)
typedef class oopDesc* oop;

class oopDesc{
    friend class VMStructs;
 private:
  volatile markOop  _mark;
  union _metadata {
    Klass*      _klass;
    narrowKlass _compressed_klass;
  } _metadata;
}
复制代码

2.一、 oop的继承体系

  • 取自jdk8,从源码能够看出xxOop是xxxOopDesc*的别名。
typedef class oopDesc* oop;
typedef class instanceOopDesc* instanceOop;
typedef class arrayOopDesc* arrayOop;
typedef class objArrayOopDesc* objArrayOop;
typedef class typeArrayOopDesc* typeArrayOop;
复制代码
  • 主要是instanceOopDesc和arrayOopDesc。均继承自oopDesc,没有扩充字段属性,下文不在赘述。也就是说instanceOopDesc、arrayOopDesc的markword、klass属性均来自oopDesc,关于arrayOopDesc稍微有点特殊,下文详述。

2.2 、InstanceOopDesc

  • 普通的Java对象均是instanceOopDesc,不管是包装类型仍是基本类型。
  • 🌰来了。

  • 可见普通类型的对象也被安排一个object header。

2.三、arrayOopDesc

  • objArrayOopDesc、typeArrayOopDesc继承自arrayOopDesc,其中包装类型的数组类型是objArrayOopDesc,基本类型数组是typeArrayOopDesc。

  • 上文提到了oop的属性,其中arrayOopDesc有点特殊,它不只有markword、klass,还有个length属性来记录数组长度。可是翻看jdk源码,arrayOopDesc除了继承自arrayOopDesc,也没有扩展任何属性,那length属性怎么来的呢?其实这个length属性属于对象头的一部分,它不是以一个独立属性的形式存在,而是在对象头markword和klass以后固定的位置存储的一个值。
  • 下面简单示意能够看出,64位虚拟机下,length出如今offset=16的位置。其中三、4等于数组长度毫不是偶然的,读者能够自行验证。

  • 注意:对象头与实例数据无关,其实arrayOopDesc的length属于对象头,不属于data的一部分。

2.四、markword

  • markword是oop的一部分,其中hashcode、GC、轻量级锁/重量级锁/偏向锁、分代年龄都是在markword上作文章。markword起始于对象头offset=0的位置,在64位虚拟机上占8个字节。

  • 上面这张图你们都见过不少次了,从名称中也能够看出我上面一点所言不虚。那么问题来了,不少人一眼看出你这篇文章上面8个字段64个bit好像除了一个看到个1,你没有锁标志我能理解,hashcode你也吃了吗?你随便写几个对象hashcode都是0吗?
  • 最开始我也诧异我骨骼惊奇(感受能够人脑挖矿、手算md5了),开个玩笑。。。java这么容易hash膨胀,我要不要转行php?骚年,是你书读的太少啊。🌰来了。

  • 仔细看图,相信你就明白了。注意markword=00000008807e2501,其中unused25位,hashcode与integers1.hashcode()相等,2个标志位也ok。jvm

  • 再看一个偏向锁状态的(标志位101)oop

三、小结

  • 主要介绍了java对象头oop,包括实例对象头、数组对象头。
  • 对对象头中的markword结合demo进行简单说明,抛砖引玉。至于偏向锁、轻量级锁、重量级锁升级过程的markword的变化待后续可能有详尽篇幅。不过都是在java对象头中作文章,读者能够结合锁升级流程图自行验证。
相关文章
相关标签/搜索