首页 > 系统相关 >对象的内存布局解析

对象的内存布局解析

时间:2022-09-18 18:56:00浏览次数:95  
标签:字节 对象 虚拟机 布局 内存 数组 解析 指针

概念说明

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

    • 对象头:比如 hash码,对象所属的年代,对象锁,锁状态标志,偏向锁(线程)ID,偏向时间,数组长度(数组对象才有)等。
    • 实例数据:存放类的属性数据信息,包括父类的属性信息;
    • 对齐填充:由于虚拟机要求 对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。

  内存布局图示:


                  

 

对象头详解

  HotSpot虚拟机的对象头包括:

    1.Mark Word

      用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。

      这部分数据的长度在32位和64位的虚拟机中分别为32bit和64bit,官方称它为“Mark Word”。(要知道1字节为8bit,故非8字节即4字节。)

    2.Klass Pointer(它的类元数据的指针)

      对象头的另外一部分是klass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

      32位4字节,64位开启指针压缩或最大堆内存<32g时4字节,否则8字节。(故非8字节即4字节。)

      jdk1.8默认开启指针压缩后为4字节,当在JVM参数中关闭指针压缩(-XX:-UseCompressedOops)后,长度为8字节。

    3.数组长度(只有数组对象有)

      如果对象是一个数组, 那在对象头中还必须有一块数据用于记录数组长度。 4字节。非数组对象则是0。

 

使用JOL工具查看内存布局(验证理论步骤)

  JOL工具说明

    查看普通java对象的内部布局工具JOL(JAVA OBJECT LAYOUT),使用此工具可以查看new出来的一个java对象的内部布局,以及一个普通的java对象占用多少字节。

    引入maven依赖(在pom.xml文件处添加)

<!-- 查看Java 对象布局、大小工具 -->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

 

  使用方法

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

  测试

    案例代码

public class ObjectJolTest {
    public static void main(String[] args) {
        Object obj = new TestObject1();
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
        Object obj2 = new TestObject2();
        System.out.println(ClassLayout.parseInstance(obj2).toPrintable());
    }
}

class TestObject1{}
class TestObject2{
    private boolean flag;
    private long  p;
}

 

    案例分析

      1. 针对TestObject1类产生的对象,利用jol查看64位系统java对象(空对象),默认开启指针压缩,总大小显示16字节,前12字节为对象

      额外拓展说明:

        • OFFSET:偏移地址,单位字节;
        • SIZE:占用的内存大小,单位为字节;
        • TYPE DESCRIPTION:类型描述,其中object header为对象头;
        • VALUE:对应内存中当前存储的值,二进制32位;

      2. 针对TestObject2类产生的对象,利用jol查看64位系统java对象(非空对象),默认开启指针压缩,总大小显示24字节,前12字节为对象

 

 

 

      3. 关闭指针压缩后:-XX:-­UseCompressedOops(元数据指针的压缩没了,恢复为8字节,进而导致有可能需要填充的变为不需要填充,或者需要填充更多)

 

 

 

  验证问题:例子中的对象占多少个字节?

    对象代码展示

class TestObject3{
    private int[] a = new int[6];
    private String[] b;
    private boolean flag;
}

    对象分析

      以之前分析可得,在开启压缩条件下,该对象为非数组对象,所以 Mark Word为8字节+Klass Pointer(元数据指针)为4字节+数组长度0字节。

      可得对象头为12字节,然后实例数据:布尔值1字节+int数组对象4字节+String数组对象4字节,故实例数据9字节。

      合计21字节,再依据对象字节数要为8的整数倍,所以应为24字节,填充3字节

    分析验证

 

 

 

    针对数组对象的分析

      代码展示

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

      对象分析

 

 

 

TestObject1

标签:字节,对象,虚拟机,布局,内存,数组,解析,指针
From: https://www.cnblogs.com/chafry/p/16705239.html

相关文章

  • 2021年3月-第02阶段-前端基础-移动WEB开发-移动WEB开发之_响应式布局
    移动端WEB开发之响应式布局1.0响应式开发原理1.1响应式开发原理就是使用媒体查询针对不同宽度的设备进行布局和样式的设置,从而适配不同设备的目的。设备的划分情况:......
  • 2021年3月-第02阶段-前端基础-移动WEB开发-移动WEB开发_rem布局
    移动web开发之rem布局rem基础rem单位rem(rootem)是一个相对单位,类似于em,em是父元素字体大小。不同的是rem的基准是相对于html元素的字体大小。比如,根元素(html)设置fo......
  • RocketMQ实战与原理解析-杨开元.pdf
    这是一本学习RocketMQ实战与实现原理的非常好的资料,内容言简意赅,非常适合初学者和对RocketMQ有一定使用经验的人,能够快速从全局层面掌握RocketMQ设计思想与核心实现。点击......
  • SAP UI5 SimpleForm 在 size XL 下的布局开发
    如果表单包含单个表单组,请使用标签字段比例为3:5:4的单列布局(标签使用3个网格列,字段使用5个网格列,以及空列)。如果将表单放入全屏应用程序中,您还可以使用属性sing......
  • SAP UI5 SimpleForm 的 two-column layout 布局
    如果您将表单放置在全屏应用程序中并且它包含多个表单组,请使用标签字段比例为12:12:0的两列布局(标签使用12个网格列,标签使用12个网格列字段和空列使用的0个网格列......
  • 2022上半年软件设计师真题解析
    选择题 ......
  • rtmp流程解析
    如果rtmp推流地址:rtmp://服务器地址:rtmp端口/路径/名称对应的websocket地址:ws://服务器地址:websocket端口/路径/名称.flv举例:live作为路径,s作为流名称,rtmp端口是1932那......
  • JavaGUI(一)——布局
    AWT编程AWT简介当JDK1.0发布时,Sun公司提供了一套基本的GUI类库,这个GUI类库希望可以在所有平台下都能运行,这套基本类库被称为“抽象窗口工具集(AbstractWindowToolkit)”,......
  • SpringBoot + Caffeine实现本地缓存(内存缓存)
    1.Caffeine简介  Caffeine是一个基于Java8开发的提供了近乎最佳命中率的高性能的缓存库。借鉴GoogleGuava和ConcurrentLinkedHashMap的经验,实现内存缓存。  缓存和......
  • Linux内核参数-共享内存
    在数据库配置过程中经常会遇到系统内核参数配置,而其中比较关键的有关于共享内存参数的配置首先解释几个定义共享内存共享内存,顾名思义即系统中两个或多个进程可以共同访......