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.

posted @   杨岂  阅读(191)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
历史上的今天:
2020-03-23 JVM锁优化
点击右上角即可分享
微信分享提示