使用JOL工具查看内存布局,查看对象的成员变量的大小、偏移量、对齐方式等信息朝夕时

JOL是Java对象布局分析工具,用于分析对象在内存中的布局,包括对象头、实例数据和对齐填充等信息。通过显示对象成员的大小、偏移量、类型等,帮助进行性能优化和调试。开发者可以通过Maven引入JOL库,使用API获取对象内部详细信息。JOL的输出会因JVM实现和参数不同而有所差异,关注对象实例大小和对齐填充对内存占用的影响。
摘要由CSDN通过智能技术生成

JOL(Java Object Layout)是一个Java对象布局分析工具。它可以帮助开发人员分析Java对象在内存中的布局,查看对象的成员变量的大小、偏移量、对齐方式等信息。JOL是基于OpenJDK的HotSpot虚拟机实现的,可以在程序运行时动态分析对象布局,非常适合用于Java性能优化和调试。

JOL工具可以执行以下任务:

  1. 显示Java对象的内部布局,包括对象头、实例数据、对齐填充等信息。
  2. 显示对象成员的大小、偏移量、类型等信息。
  3. 显示对象成员的对齐方式和填充情况。
  4. 显示对象的哈希码、类名等信息。
  5. 支持解析Java对象的压缩指针(Compressed Oops)格式。

使用JOL工具可以帮助开发人员更好地理解Java对象的内部结构和存储方式,从而优化Java程序的性能,避免内存泄漏和其他问题。JOL工具非常易于使用,只需要在项目中引入JOL的依赖项,然后在代码中调用JOL的API即可。

maven引入

 <dependency>
     <groupId>org.openjdk.jol</groupId>
     <artifactId>jol-core</artifactId>
     <version>0.10</version>
 </dependency>
复制代码

使用方法

// 查看对象内部信息
System.out.println(ClassLayout.parseInstance(obj).toPrintable());
复制代码

测试代码1

public class JolTest {
    public static void main(String[] args) {
        Object obj = new Object();
        // 查看对象内部信息
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
    }
}
复制代码

输出结果

其中,每一行输出表示一个成员变量或对象头的信息,具体含义如下:

  • OFFSET:成员变量或对象头的偏移量,相对于Java对象的起始地址。
  • SIZE:成员变量或对象头的大小,以字节为单位。
  • TYPE:成员变量或对象头的类型,包括Java基本类型和对象类型。
  • DESCRIPTION:成员变量或对象头的描述信息,包括成员变量的名称和类型。
  • VALUE:成员变量或对象头的值,以16进制表示。对于对象头,包括Mark Word和Klass Pointer等信息。
  • Instance size:对象实例的大小,包括对象头、实例变量和对齐填充的总大小。
  • Space losses:对象实例中的空间损失,包括对象内部的空间损失和对象外部的空间损失。

需要注意的是,JOL工具输出的信息可能会因不同的JVM实现和不同的JVM参数而有所不同,因此在使用JOL工具时需要注意选择合适的环境和参数。

测试代码2

public class JolTest {
    public static void main(String[] args) {
        Object obj = new Test();
        // 查看对象内部信息
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
    }
}
class Test{
    private long p;
    
}
复制代码

测试代码3

public class JolTest {
    public static void main(String[] args) {
        Object obj = new Test();
        // 查看对象内部信息
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
    }
}
class Test{
    private long p;
    private byte p1;
    private short p2;
}
复制代码

为什么对象实例的大小(Instance size)还是24?

因为alignment/padding gap进行了字节的对齐填充,如果其他变量比如byte和short加起来没有超过对齐填充的大小还是算加上了对齐填充的大小。

DESCRIPTION的“alignment/padding gap”是什么意思?

在JOL工具的输出结果中,每个成员变量或对象头的信息前面都有一个"DESCRIPTION"字段,它包含成员变量或对象头的名称和类型等描述信息。其中,如果成员变量或对象头的偏移量不是8的倍数,JOL会在该字段后面显示一个"alignment/padding gap"字段,表示在该成员变量或对象头后面添加了多少字节的对齐填充。

对齐填充是指在成员变量或对象头之间添加一些字节,以保证它们的偏移量都是8的倍数。这样做的原因是为了提高访问成员变量或对象头的效率,因为访问8字节对齐的变量比非对齐变量更快。对齐填充的大小取决于成员变量或对象头的大小和偏移量等因素,因此可能会在输出结果中出现"alignment/padding gap"信息。

需要注意的是,对齐填充在内存中不占用任何有意义的数据,只是为了对齐而填充的字节。因此,对齐填充的大小可能会影响Java对象的内存占用大小,但不会影响对象的实际内容。

java中各个类型都占用多少个字节?

以下是Java中各个基本数据类型的大小(占用字节数):

  • byte:1个字节(8位)
  • short:2个字节(16位)
  • int:4个字节(32位)
  • long:8个字节(64位)
  • float:4个字节(32位)
  • double:8个字节(64位)
  • char:2个字节(16位)
  • boolean:1个字节(8位),但是实际上只使用其中1个bit,取值为true或false。

需要注意的是,Java中的基本数据类型大小和具体实现有关,不同的JVM实现可能会有所不同。此外,Java中的引用类型(如Object、String等)大小取决于具体实现和对象的内容,因此无法给出固定大小。

作者:朝夕时
链接:https://juejin.cn/post/7226357340060647485
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值