java对象由三部分组成:对象头,实例数据,对齐填充。
官方文档中也明确指出:http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html
对象头中就包括Mark Word和Class Pointer。
Mark Word包括对象hashCode,GC信息和锁信息。(32位JVM下 Mark Word如下表所示)
然而上表仅仅是表示 32JVM 下的 Mark Word信息, 我们可以在openjdk源码中的 markOop.hpp 文件中看到
附上官网 openjdk 源码地址 可自行下载:https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/4687075d8ccf
其中 markOop.hpp 文件一般都在目录 hotspot\src\share\vm\oops 下
从源码中看到我们现在使用的 64位 JVM 的 Mark Word 已经有所改变(具体如上图所示)
前31位的 hashcode 存的是对象的地址---转为hashcode形式
Age存的是Gc的年龄占4位---------最大值15,达到最大值时 java 对象由 新生代转至老年代
Baised_lock偏向锁 1位与Lock 锁信息 2位 用来记录 锁的 5 种状态
了解完这些基础知识,下面我们就来看看具体的对象头信息------借助工具 jol
我们可以在 maven 项目中导入依赖
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
接下来测试一下 对象 的具体组成
package com.wjj;
import org.openjdk.jol.info.ClassLayout;
public class SychronizedTest {
public static void main(String[] args) {
L l = new L();
//System.out.println("l对象的hashcode: "+Integer.toHexString(l.hashCode()));
System.out.println(ClassLayout.parseInstance(l).toPrintable());
}
}
class L{
boolean flag = false;
//int num;
}
结果如下
在这里我们就可以看出
64位虚拟机下一个空对象至少要占16字节,32位虚拟机下一个空对象至少要占8个字节
对象由三部分组成:对象头,实例数据,对齐填充(8的倍数)
对象头中包括mark word标记头(64位虚拟机占8个字节,32位虚拟机占4个字节)和class point(占4个字节)
实例数据:空对象无实例数据,占0个字节
对齐填充至8的倍数
所以,64位虚拟机下一个空对象占16个字节,32位虚拟机占8个字节
我们还可以以16进制的形式打印一下对象的 hashcode 信息看看与对象头中Mark word中是否一致
System.out.println("l对象的hashcode: "+Integer.toHexString(l.hashCode()));
我们可以看到其实 对象头中的存储与对象的 hashcode 完全一致,只不过 Mark word是反向存储。