Klass指针和Mark Word
[[类加载]]
### Klass 对象
在 Java 虚拟机(JVM,基于 HotSpot 实现)中,Klass 对象 是 JVM 用来表示类的元数据的内部数据结构。它存储在方法区(JDK 1.8 之前) 或 元空间(Metaspace,JDK 1.8 及之后) 中,用于描述一个 Java 类的结构和信息。
- 作用:Klass 对象包含类的元信息,例如:
- 类名、父类、接口
- 方法表、字段表、常量池
- 静态变量(类变量)的存储位置
- 类加载器信息
- 访问修饰符(如 public、final 等)
- 内存布局:Klass 对象是 JVM 内部的 C++ 对象(在 HotSpot 中),每个加载的 Java 类对应一个 Klass 对象(或其子类型,如 InstanceKlass、ArrayKlass 等)。它不直接暴露给 Java 代码,而是由 JVM 用于管理和访问类的元数据。
- 实例关系:堆中的每个 Java 对象通过其对象头中的 Klass 指针(指向 Klass 对象)关联到对应的类元数据,从而知道自己属于哪个类。
Mark Word¶
Mark Word 是 Java 对象在堆内存中的对象头的一部分,用于存储对象的运行时元数据。它的大小和内容因 JVM 实现和架构(32 位或 64 位)而异,通常用于支持垃圾回收、锁机制等功能。
- 作用:Mark Word 存储以下信息(具体内容动态变化):
- 锁状态:记录对象的锁信息(如无锁、偏向锁、轻量级锁、重量级锁)。
- 哈希码:对象的
hashCode()值(调用System.identityHashCode()时生成)。 - 分代年龄:用于垃圾回收,记录对象在年轻代的存活次数。
- GC 标记:垃圾回收期间的标记信息(例如标记-清除算法中的标记位)。
- 内存布局:
- 在 32 位 JVM 中,Mark Word 通常占 4 字节。
- 在 64 位 JVM 中,Mark Word 占 8 字节(即使开启指针压缩)。
- Mark Word 的内容是动态的,根据对象状态(如是否被锁、GC 状态)会切换格式。例如,偏向锁会存储线程 ID,无锁状态可能存储哈希码。
- 示例结构(64 位 JVM,简化的 Mark Word 布局):
具体位分配因锁类型(如偏向锁、轻量级锁)而变化。
Klass 对象与 Mark Word 的关系¶
- Klass 指针:对象头的另一部分(通常紧跟 Mark Word)是 Klass 指针,指向方法区/元空间中的 Klass 对象,用于标识对象的类。
- 对象头完整结构(以 64 位 JVM,开启指针压缩为例):
- 对象头 = Mark Word(8 字节) + Klass 指针(4 字节,压缩后) + 对齐填充(可能 4 字节)。
- 总大小通常为 16 字节(满足 8 字节对齐)。
- 协作:Mark Word 管理对象的运行时状态(如锁、GC),而 Klass 指针通过指向 Klass 对象,连接到类的元数据(如方法、字段),从而支持对象的类型信息和行为。
总结¶
- Klass 对象:JVM 内部表示类元数据的 C++ 数据结构,存储在方法区/元空间,包含类的静态变量、方法表等信息。
- Mark Word:对象头的一部分,存储对象的运行时元数据(如锁状态、哈希码、分代年龄),用于支持锁机制和垃圾回收。
- 两者共同协作,Klass 对象提供类的静态信息,Mark Word 提供实例的动态状态,构成了 Java 对象内存布局的核心。
如果你需要更详细的内存布局分析(例如用 JOL 工具查看),可以告诉我!