• Java对象内存布局


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

    另外,Java中对象的内存布局分为两种情况,非数组对象和数组对象,区别是数组对象头中需要额外的空间存储数组的长度length。

     

    对象头(Object Header)

       对象头又分为MarkWord和Class Pointer。

    • MarkWord:标记存储对象本身运行时的数据,包含哈希值(指向对象在堆中的首地址值)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。在32位系统占4字节,在64位系统中占8字节

    • ClassPointer:类型指针,存储的是对象指向它的Class对象(其对应的类元数据对象)的首地址。在32位系统占4字节,在64位系统中占8字节

    • Length:只在数组对象中存在,用来记录数组的长度,占用4字节

      对象头中Mark Word 在不同状态下的存储内容如下:

    锁状态 存储内容(剩余bit) 是否为偏向锁(1bit) 锁标志位(2bit)
    无锁 对象哈希码、分代年龄 0 01
    偏向锁 偏向线程ID、偏向时间戳、对象分代年龄 1 01
    轻量级锁 指定锁记录的指针 无此bit 00
    重量级锁 指向重量级锁的指针 无此bit 10
    GC标记 空,不需要记录记录信息 无此bit 11

      

    实例数据(Instance data)

    • Instance data:对象实例数据,存储本类对象的成员变量和所有可见的父类成员变量。(这里不包括静态成员变量,因为其是在方法区维护的)

     

    对齐填充(Padding)

    • Padding:Java对象的存储空间分配单位是8个字节,不足8字节,也会分配8字节进行填充。即所有Java对象占用bytes数必须是8的倍数,padding的作用就是补充字节,保证对象是8字节的整数倍。64位计算机上Java对象头的大小刚好是8的2倍,因此当实例数据部分没有对齐时,就需要通过对齐填充来补全。

    指针压缩

       -XX:+UseCompressedOops 可以压缩指针,将占用的空间压缩为原来的一半(4字节),起到节约空间的作用,classpointer参数大小就受到其影响。

     

    Object o = new Object()到底占用多少个字节?

    • 在开启指针压缩的情况下,markword占用8字节,classpoint占用4字节,Instance data无数据,总共是12字节,由于对象需要为8的整数倍,Padding会补充4个字节,总共占用16字节的存储空间。

    • 在没有指针的情况下,markword占用8字节,classpoint占用8字节,Instance data无数据,总共是16字节。

    END.

  • 相关阅读:
    THINKPAD E40部分问题解疑(抛砖引玉……)
    VS 智能感知失效问题的解决方法
    Distinct()通过使用默认的相等比较器对值进行比较返回序列中的非重复元素。
    dhl:阻止保存要求重新创建表的更改
    linq ef4.0 的联表 Include方法 代替联表操作
    l.cn 代码学习
    CSS解决未知高度垂直居中的问题
    Resharper 下载及使用方法
    网站大并发处理解决方案
    使用的 SQL Server 版本不支持数据类型“datetime2”解决办法
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/14571672.html
Copyright © 2020-2023  润新知