java 对象内存布局_JOL:分析Java对象的内存布局

本文通过JOL工具详细解析了Java对象在64位HotSpot虚拟机中的内存布局,包括对象头、实例数据及内存填充等内容,并展示了如何通过实践代码进行分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过OpenJDK官方提供的JOL(Java Object Layout)工具,我们即可很方便分析、了解一个Java对象在内存当中的具体布局情况。这里将在64位的HotSpot Java虚拟机环境下进行分析、测试

Java 对象的内存布局

Java的实例对象、数组对象在内存中的组成包括如下三部分:对象头Hearder、实例数据、内存填充。示意图如下所示对象头:其主要包括两部分数据:Mark Word、Class对象指针。特别地对于数组对象而言,其还包括了数组长度数据。在64位的HotSpot虚拟机下,Mark Word占8个字节,其记录了Hash Code、GC信息、锁信息等相关信息;而Class对象指针则指向该实例的Class对象,在开启指针压缩的情况下占用4个字节,否则占8个字节;如果其是一个数组对象,则还需要4个字节用于记录数组长度信息。这里列出64位HotSpot虚拟机Mark Word的具体含义,以供参考。需要注意的是在下图的Mark Word中,左侧为高字节,右侧为低字节实例数据:用于存放该对象的实例数据

内存填充:64位的HotSpot要求Java对象地址按8字节对齐,即每个对象所占内存的字节数必须是8字节的整数倍。因此Java对象需要通过内存填充来满足对齐要求

Note:

在64位的HotSpot虚拟机下,类型指针、引用类型需要占8个字节。显然这大大增加了内存的消耗和占用。为此从JDK 1.6开始,64位的JVM支持UseCompressedOops选项。其可对OOP(Ordinary Object Pointer,普通对象指针)进行压缩,使其只占用4个字节,以达到节约内存的目的。在JDK 8下,该选项默认启用。当然也可以通过添加JVM参数来显式进行配置

-XX:+UseCompressedOops // 开启指针压缩-XX:-UseCompressedOops // 关闭指针压缩

实践

利用JOL工具分析很简单,首先在POM添加添加其Maven依赖

org.openjdk.jol

jol-core

0.9

然后编写一个简单的Java类,以供我们进行后续分析

@Data

@Builder

public class Car {

private int id;

private String type;

private double price;

private char level;

}

下面,我们分别构造处Car对象、数组对象,然后通过JOL工具进行内存布局的分析

public class JOLDemo {

public static void main(String[] args) {

Car car = Car.builder()

.id(1)

.type("SUV")

.level('A')

.price(22.22)

.build();

System.out.println( ClassLayout.parseInstance(car).toPrintable() );

int[] array = new int[3];

array[0] = 11;

array[1] = 22;

array[2] = 33;

System.out.println( ClassLayout.parseInstance(array).toPrintable() );

}

}

这里我们设置了JVM选项-XX:-UseCompressedOops以关闭指针压缩。下面即是Java对象的内存布局信息输出及相关分析结果,这里笔者的CPU主机字节序为小端

参考文献深入理解Java虚拟机·第2版 周志明著

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值