文章目录

  • 前言
  • 一、Java对象布局
  • 二、如何进行查看
  • 1.引入依赖
  • 2.获取对象信息
  • 3、结果查看
  • 总结

前言

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

一、Java对象布局

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

java  怎样布局 java的布局_Java

  • 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  怎样布局 java的布局_Java_02

总结

以上就是今天要讲的内容