文章目录
- 前言
- 一、Java对象布局
- 二、如何进行查看
- 1.引入依赖
- 2.获取对象信息
- 3、结果查看
- 总结
前言
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、结果查看
总结
以上就是今天要讲的内容