JVM之【Java对象在内存中的结构】

发布于:2025-08-29 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

前言

对象的组成部分

对象头

实例数据

对齐填充

查看对象的组成结构和大小

添加依赖

查看Object对象占用的内存大小

查看数组对象占用的内存大小

查看上面example1占用内存大小

查看上面example2占用内存大小

相关的JVM参数


前言

Java程序运行过程中,大多数的对象会被分配到堆空间中存储,本文主要介绍Java对象在内存中的组成结构

对象的组成部分

Java对象一般由三个部分组成:对象头、实例数据和对齐填充

对象头

由如下几个部分组成

  • MarkWord,在64位虚拟机中占用8个字节
  • 类型指针,在64位虚拟机中且开启了指针压缩时占用4个字节
  • 数组长度(如果是数组对象),在64位虚拟机中占用4个字节

实例数据

下图中Example1类中有3个属性,两个int型一个long类型,此时对象example1的实例数据大小为:4+4+8=16字节

public class Example1 {
    // 4byte
    private int i1;
    // 4byte
    private int i2;
    // 8byte
    private long l1;

    public static void main(String[] args) {
        Example1 example1 = new Example1();
    }
}

下图中Example2类中有4个属性,2个int类型,1个long类型,1个引用类型(引用类型是直接存储指针的),在开启指针压缩时,example2的实例数据大小为:4+4+8+4=20字节

public class Example2 {
    // 4byte
    private int a;
    // 4byte
    private int b;
    // 8byte
    private long c;
    // 开启指针压缩占时占用4byte
    private Example1 e;

    public static void main(String[] args) {
        Example2 example2 = new Example2();
    }
}

对齐填充

在Java对象中,对齐填充可能存在也可能不存在,64位虚拟机规定Java对象的总大小必须是8的整数倍,所以当一个对象的头像头+实例数据大小不为8的整数倍时,会通过对齐填充的方式将对象的大小补齐成8的整数倍

查看对象的组成结构和大小

添加依赖

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

查看Object对象占用的内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;

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

运行结果:大小为16字节(8字节的MarkWord + 4字节的类型指针 + 4字节的对齐填充)

查看数组对象占用的内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;

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

运行结果:56字节(8字节MarkWord + 4字节类型指针 + 4字节数组长度 + 4*9字节数组空间 + 4字节对齐填充)

查看上面example1占用内存大小

代码实例

import org.openjdk.jol.info.ClassLayout;

public class WatchObj {
    public static void main(String[] args) {
        Example1 object = new Example1();
        System.out.println(ClassLayout.parseInstance(object).toPrintable());
    }
}

运行结果:32字节(有4字节的对齐填充)

查看上面example2占用内存大小

代码示例

import org.openjdk.jol.info.ClassLayout;

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

运行结果:32字节(没有对齐填充)

相关的JVM参数

  1. [-XX:+UseCompressedOops]:开启指针压缩

网站公告

今日签到

点亮在社区的每一天
去签到