深入理解 java 对象头的 Mark Word--------源码分析

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是反向存储。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值