2024-10-26  阅读(19)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://www.skjava.com/mianshi/baodian/detail/8386813329

回答

Java 对象的内存布局包括三个部分:对象头实例数据对齐填充

  • 对象头:这是对象的元数据区域,包括两个主要部分:
    • Mark Word:存储对象的运行时信息,如哈希码、GC 分代年龄、锁状态等。它是动态变化的,根据对象的状态不同而变化。
    • 类型指针(Class Pointer):指向对象对应的类的元数据,帮助 JVM 定位方法表等信息。
  • 实例数据:存储对象的实际字段值。JVM 按照字段声明的顺序来存储这些数据,同时考虑字段类型的大小。例如,int 占 4 字节,long 占 8 字节。JVM 可能会对数据进行对齐优化,以提高访问效率。
  • 对齐填充:为了确保内存访问的高效性,JVM 会对对象的大小进行内存对齐。通常对象的大小会被调整为 8 字节或 16 字节的倍数,这样可以使下一个对象从对齐的内存地址开始,减少访问时的开销。

详解

对象头

对象头分为两个主要部分:Mark Word 和类型指针。

Mark Word

Mark Word 用于存储对象自身的运行时数据,它在 32 位 JVM 中的长度是 32bit,在 64 位JVM中长度是 64bit,Mark Word对应到C++的代码markOop.hpp,可以从注释中看到它们的组成:

Mark Word在不同的锁状态下存储的内容不同。

  • 32 位 JVM

  • 64 位 JVM

虽然它们在不同位数的JVM中长度不一样,但是基本组成内容是一致的。

  • 锁标志位(lock):区分锁状态,11时表示对象待GC回收状态, 只有最后2位锁标识(11)有效。
  • biased_lock:是否偏向锁,由于无锁和偏向锁的锁标识都是 01,没办法区分,这里引入一位的偏向锁标识位。
  • 分代年龄(age):表示对象被GC的次数,当该次数到达阈值的时候,对象就会转移到老年代。
  • 对象的hashcode(hash):运行期间调用System.identityHashCode()来计算,延迟计算,并把结果赋值到这里。当对象加锁后,计算的结果31位不够表示,在偏向锁,轻量锁,重量锁,hashcode会被转移到Monitor中。
  • 偏向锁的线程ID(JavaThread):偏向模式的时候,当某个线程持有对象的时候,对象这里就会被置为该线程的ID。 在后面的操作中,就无需再进行尝试获取锁的动作。
  • epoch:偏向锁在CAS锁操作过程中,偏向性标识,表示对象更偏向哪个锁。
  • ptr_to_lock_record:轻量级锁状态下,指向栈中锁记录的指针。当锁获取是无竞争的时,JVM使用原子操作而不是OS互斥。这种技术称为轻量级锁定。在轻量级锁定的情况下,JVM通过CAS操作在对象的标题字中设置指向锁记录的指针。
  • ptr_to_heavyweight_monitor:重量级锁状态下,指向对象监视器Monitor的指针。如果两个不同的线程同时在同一个对象上竞争,则必须将轻量级锁定升级到Monitor以管理等待的线程。在重量级锁定的情况下,JVM在对象的ptr_to_heavyweight_monitor设置指向Monitor的指针。

类型指针

在 Java 中,每个对象都有一个类型指针,用于指向描述对象类型的类元数据,通过这个指针,JVM 可以确定对象的字段布局、方法实现和继承结构等信息。

实例数据

实例数据是指 Java 对象中的所有实例变量(字段),这些字段在对象被创建时分配内存,并在对象的生命周期内存储实际的值。实例数据的布局和存储方式取决于对象的类定义和字段类型。包括基本数据类型和引用类型两种。

基本数据类型的字段占用固定大小的内存,如下:

类型 占用空间(byte)
boolean 1
byte 1
short 2
char 2
int 4
float 4
long 8
double 8

引用类型存储其他对象的引用,该值指向其他对象的内存地址,其占用内存大小由与 JVM 指针大小相同,在 32 位 JVM 中是 4 字节,在 64 位 JVM 中是 8 字节。

对齐填充

为了确保内存访问的高效性,JVM 会对对象的大小进行内存对齐。通常对象的大小会被调整为 8 字节或 16 字节的倍数,这样可以使下一个对象从对齐的内存地址开始,减少访问时的开销。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文