自学内容网 自学内容网

Java对象的内存分布(一)

一、概览

在Hotspot虚拟机中,java对象在内存中分布如下图所示:

+---------------+---------------+---------------+
|   对象头       |   实例数据   | 对齐填充    |
+---------------+---------------+---------------+
对象大小 = 对象头 + 实例数据 + [填充数据]
  • 对象头:任何对象都包含对象头,用于存储该对象的class类型指针、GC年龄、HashCode、锁标志等信息;
  • 实例数据:业务定义的数据;
  • 对齐填充
    • java规定内存默认使用8字节对齐,方便寻址,提升效率(以空间换时间);
    • 该部分不是必需的,即前面对象头和实例数据的大小之和不是8的倍数(8N),则补齐空间到8N;否则,无需对齐填充部分。
    • 对齐8字节这个参数可以通过JVM参数-XX:ObjectAlignmentInBytes来改变(默认值为8)。当然这个数值的必须是2的次幂,数值范围需要在8 - 256之间。

二、代码实例

2.1、 准备工作

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

2.2 、代码

import org.openjdk.jol.info.ClassLayout;

public class Head {
    public static void main(String[] args) throws InterruptedException {

        System.out.println("查看 Empty 对象");
        System.out.println(ClassLayout.parseInstance(new Empty()).toPrintable());

        System.out.println("查看 UserPadding 对象");
        System.out.println(ClassLayout.parseInstance(new UserPadding()).toPrintable());

        System.out.println("查看 UserNoPadding 对象");
        System.out.println(ClassLayout.parseInstance(new UserNoPadding()).toPrintable());
    }

    static class Empty{}

    static class UserPadding{
        int age;  // 4个字节
        long date; // 8个字节
        String name; // 4个字节
    }

    static class UserNoPadding extends UserPadding{
        int salary;
    }
}

2.3、运行结果在这里插入图片描述

附:

  • OFFSET:表示偏移量
  • SIZE:占用字节大小
  • TYPE:具体类型
  • DESCRIPTION:字段名称;(object header)为对象头
  • VALUE:取值,基本类型存的就是实际值,引用类型存的是指针
  • 当前运行jvm为 64-bit HotSpot VM

2.4、分析

2.4.1、Empty对象

  • 对象头:占用12(4+4+4)字节
  • 实例数据:占用0(该对象没有业务数据)
  • 对齐填充:前面一共占用12(12 + 0)字节,填充4字节使得整个对象占用16字节,对齐8N;

2.4.2、UserPadding对象

  • 对象头:占用12(4+4+4)字节
  • 实例数据:占用16字节(int 4字节,long 8字节, String 4字节指针)
  • 对齐填充:前面一共占用28(12 + 16)字节,填充4字节使得整个对象占用32字节,对齐8N;

2.4.3、UserNoPadding对象

  • 对象头:占用12(4+4+4)字节
  • 实例数据:占用20字节(2个 int 8字节,long 8字节, String 4字节指针)
  • 对齐填充:前面一共占用32(12 + 20)字节,已经对齐8N,无需填充;

2.4.4、业务数据的默认值

观察UserPadding对象的业务数据默认值(用户并未显示指定值),可以看到:

  • 数据类型默认为0;
  • 引用类型默认null

原文地址:https://blog.csdn.net/xiaolingting/article/details/144711293

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!