2.Java对象头
HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
普通对象的对象头包括两部分:Mark Word 和 Class Metadata Address (类型指针),如果是数组对象还包括一个额外的Array length数组长度部分。
Mark Word:用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,占用内存大小与虚拟机位长一致。
Class Metadata Address:类型指针指向对象的类元数据,虚拟机通过这个指针确定该对象是哪个类的实例。
Array length:数组长度
如果对象是数组类型,则虚拟机用3个Word(字宽)存储对象头,如果对象是非数组类型,则用2字宽存储对象头。在32位虚拟机中,一字宽等于四字节,即32bit。
| 长度 | 内容 | 说明 |
|---|---|---|
| 32/64bit | Mark Word | 存储对象hashCode或锁信息等运行时数据。 |
| 32/64bit | Class Metadata Address | 存储到对象类型数据的指针 |
| 32/64bit | Array length | 数组的长度(如果当前对象是数组) |
对象需要存储的运行时数据很多,其实已经超出了32、64位Bitmap结构所能记录的限度,但是对象头信息是与对象自身定义的数据无关的额外存储成本,考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。例如在32位的HotSpot虚拟机 中对象未被锁定的状态下,MarkWord的32个Bits空间中的25Bits用于存储对象哈希码(HashCode),4Bits用于存储对象分代年龄,2Bits用于存储锁标志位,1Bit固定为0,在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容如下表所示。
图片来源于https://www.jianshu.com/p/0ac84319e787
作者:foofoo
链接:https://juejin.im/post/5b90cd7c5188255c877e20c8
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。