Java对象布局(内存模型/结构)


前言

Java是面向对象编程,那么了解对象可以进一步提高我们对于Java的了解。本文就简要介绍Java对象布局,即JOL((java object layout)。


一、Java对象布局

参考博客

我们先了解一下,一个JAVA对象的存储结构。在Hotspot虚拟机中,对象在内存中的存储布局分为 3 块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。如下图所示:
在这里插入图片描述

  • MarkWord:用于存储对象运行时的数据,比如HashCode、锁状态标志、GC分代年龄等。这部分在64位操作系统下,占8字节(64bit),在32位操作系统下,占4字节(32bit)。详细可参考博客
  • klasspoint:固定长度4byte, 指定该对象的class类对象(默认使用-XX:+UseCompressedClassPointers 参数进行压缩,可使用-XX:-UseCompressedClassPointers关闭,则该字段在64位jvm下占用8个字节;可使用java -XX:+PrintCommandLineFlags -version 命令查看默认的或已设置的jvm参数)。
  • length:这部分只有是数组对象才有,如果是非数组对象,就没这部分了,这部分占4字节(32bit)。
  • instance data:用于存储对象中的各种类型的字段信息(包括从父类继承来的)。
  • padding:java对象的大小默认是按照8字节对齐,也就是说java对象的大小必须是8字节的倍数。如果算到最后不够8字节的话,那么就会进行对齐填充。
    那么为什么非要进行8字节对齐呢?这样岂不是浪费了空间资源?
Scott oaks在书上给出的理由是:
其实在JVM中(不管是32位的还是64位的),对象已经按8字节边界对齐了;对于大部分处理器,这种对齐方案都是最优的。所以使用压缩的oop并不会损失什么。如果JVM
中的第一个对象保存到位置0,占用57字节,那下一个对象就要保存到位置64,浪费了7
字节,无法再分配。这种内存取舍是值得的(而且不管是否使用压缩的oop,都是这样),因为在8字节对齐的位置,对象可以更快地访问。
不过这也是为什么JVM没有尝试模仿36位引用(可以访问64GB的内存)的原因。在那种情况下,对象就要在16字节的边界上对齐,在堆中保存压缩指针所节约的成本,就被为对齐对象而浪费的内存抵消了。

也就说,8字节对齐,是为了效率的提升,以空间换时间的一种方案。当然你还可以16字节对齐。但是8字节是最优选择。

二、如何进行查看

1.引入依赖

		<dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.10</version>
            <scope>provided</scope>
        </dependency>

2.获取对象信息

代码如下:

		Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());

3、结果查看

在这里插入图片描述


总结

以上就是今天要讲的内容,本文仅仅简单介绍了Java对象布局,未对每个字段进行详细分析,感兴趣可以查看上文中推荐的博客,个人就不重复造轮子了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值