一、对象分布
1.1、分布
根据java虚拟机规范里面的描述:java对象分为三部分:对象头(Object Header), 实例数据(instance data),对齐填充(padding,无论32位、64位虚拟机都是8字节对齐)。如图
对象头包括:mark word和class pointer,其中class pointer代表当前类属于哪个class文件
32位虚拟机 | 64位虚拟机 | |
mark word | 8字节 | 8字节 |
class pointer | 4字节 | 4字节 |
在64位虚拟机中,默认启用压缩class pointer功能,所以64位和32位的对象头是一样,可以通过-XX:-UseCompressedClassPointers取消压缩
1.2、查看默认参数
通过参数PrintCommandLineFlags显示默认参数,相关于java命令无参数执行
[root@localhost ~]$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2147483648 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_265-b01)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.265-b01, mixed mode)
[root@localhost ~]$
-XX:+UseCompressedClassPointers 启用压缩类指针
-XX:+UseCompressedOops 启用压缩Oops (Oriented Object Pointer)
二、mark word具体内容
下面我们以对象(Ojbect)为例分析每一部分组成。数组与对象类似,只是对象头部分多了数组长度Length的存储长度为4字节。
Mark Word存储了对象的hashCode、GC信息、锁信息三部分,Class Pointer存储了指向类对象信息的指针。在32位JVM上对象头占用的大小是8字节,64位JVM则是16字节,两种类型的Mark Word 和 Class Pointer各占一半空间大小。
在64位JVM上有一个压缩指针选项-XX:+UseCompressedOops,默认是开启的。开启之后Class Pointer部分就会压缩为4字节,此时对象头大小就会缩小到12字节。
下面是用一张图展示 32位JVM上对象头的内存分布,方便理解,注意:分代年龄最多是4bit,也就是最大是15。
64位分布: