简述对象内存布局

对象内存布局

HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

1. 对象头

Java对象的对象头由三部分组成:

  1. Mark Word
  2. 类型指针
  3. 数组长度(只有数组对象有)

1.1 Mark Word

MarkWord用于存储对象自身的运行时数据, 如哈希码(HashCode)、GC分代年龄、锁信息等等。

Mark Word在32位JVM中的长度是32bit,在64位JVM中长度是64bit。

例如在32位的HotSpot虚拟机中对象未被锁定的状态下,Mark Word32个bits空间中的25bits用于存储对象哈希码(HashCode),4bits用于存储对象分代年龄,2bits用于存储锁标志位,1bit固定为0,在其他状态(轻量级锁定、重量级锁定、GC标记、可偏向)下对象的存储内容如下表所示。

在这里插入图片描述

1.2 类型指针

该指针在32位JVM中的长度是32bit,在64位JVM中长度是64bit。

类型指针指向对象的类元数据,虚拟机通过这个指针确定该对象是哪个类的实例。

Java对象的类数据保存在方法区。

1.3 数组长度

如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度。

这部分数据的长度也随着JVM架构的不同而不同:32位的JVM上,长度为32位;64JVM则为64位。

64位JVM如果开启+UseCompressedOops选项,该区域长度也将由64位压缩至32位

2. 实例数据

对象的实例数据就是在java代码中能看到的属性和他们的值。

3. 对齐填充字节

因为JVM要求Java的对象占的内存大小应该是8bit的倍数,所以后面有几个字节用于把对象的大小补齐至8字节的倍数,没有特别的功能。

4. 使用JOL来分析java的对象布局

JOL的全称是Java Object Layout。是一个用来分析JVMObject布局的小工具。包括Object在内存中的占用情况,实例对象的引用情况等等。

JOL可以在代码中使用,也可以独立的以命令行中运行。命令行的我这里就不具体介绍了,今天主要讲解怎么在代码中使用JOL

使用JOL需要添加maven依赖:

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

通过JOL查看jvm信息:

public class Test01 {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

输出:

在这里插入图片描述

先解释下各个字段的含义

  • OFFSET是偏移量,也就是到这个字段位置所占用的byte数,
  • SIZE是后面类型的大小,
  • TYPE是Class中定义的类型,
  • DESCRIPTION是类型的描述,
  • VALUETYPE在内存中的值。

从上图可以看出Object o = new Object(); 在内存中占16个字节。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值