java对象头学习
术语参考:http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。如下图所示:
_mark表示对象标记、属于markOop类型,它记录了对象和锁有关的信息; Klass表示普通指针; _compressed_klass表示压缩类指针。
Mark Word
Mark Word用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,占用内存大小与虚拟机位长一致。
Klass pointer
64位虚拟机则其Klass pointer的大小为64位; 一般来说虚拟机都会开启指针压缩;即也就是说在64位虚拟机情况下其Klass pointer也会被压缩成32位;
一些特殊类型的指针JVM不会优化,
比如执行PermGen的Class对象指针(JDK8中指向元空间的Class对象指针)、本地变量、堆栈元素、入参、返回值和NULL指针等。
对象头 = Mark Word + 类型指针(未开启指针压缩的情况下)
在64位系统中,Mark Word = 8 bytes, 类型指针 = 8bytes, 对象头 = 16bytes = 128 bits;
实例数据
实例数据:对象实例数据(堆):对象中各个实例字段的数据 ##下面作为额外的知识 对象类型数据(方法区):对象的类型、父类、实现的接口、方法等 静态区(也在方法区中)用来存放静态变量,静态块
对齐填充
对齐填充并不是必然存在的,占位符的作用。由于HotSpot VM的自动内存管理系统 要求对象起始地址必须是8字节的整数倍。换句话说,就是对象的大小必须是8字节的整数倍。而对象头正好是8字节的整数倍,因此,当对象实例数据没有对齐时,就需要通过对齐填充来补全。
再64为虚拟机中运行时其存储结构如下: