java基础-Java 对象头(Object Header)结构

Java 对象头(Object Header)结构

Java 对象在内存中的存储布局分为三部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。其中对象头是理解 Java 锁机制、GC 等关键功能的基础。

一、对象头组成

对象头包含两部分(32位和64位系统结构不同):

1. Mark Word(标记字段)

存储对象自身的运行时数据,长度与系统位数相同(32位/64位)

2. Klass Pointer(类型指针)

指向对象元数据的指针,JVM 通过它确定对象是哪个类的实例

注意:如果开启指针压缩(-XX:+UseCompressedOops,默认开启),64位系统的 Klass Pointer 为32位

二、Mark Word 详细结构

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

32位虚拟机下的结构

lua 复制代码
|-------------------------------------------------------|--------------------|
|                  Mark Word (32 bits)                  |       State        |
|-------------------------------------------------------|--------------------|
| identity_hashcode:25 | age:4 | biased_lock:1 | lock:2 |       Normal       |
|-------------------------------------------------------|--------------------|
|  thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:2 |       Biased       |
|-------------------------------------------------------|--------------------|
|               ptr_to_lock_record:30          | lock:2 | Lightweight Locked |
|-------------------------------------------------------|--------------------|
|               ptr_to_heavyweight_monitor:30   | lock:2 | Heavyweight Locked |
|-------------------------------------------------------|--------------------|
|                                              | lock:2 |    Marked for GC   |
|-------------------------------------------------------|--------------------|

64位虚拟机下的结构

lua 复制代码
|------------------------------------------------------------------------------|--------------------|
|                          Mark Word (64 bits)                                 |       State        |
|------------------------------------------------------------------------------|--------------------|
| unused:25 | identity_hashcode:31 | unused:1 | age:4 | biased_lock:1 | lock:2 |       Normal       |
|------------------------------------------------------------------------------|--------------------|
| thread:54 |       epoch:2        | unused:1 | age:4 | biased_lock:1 | lock:2 |       Biased       |
|------------------------------------------------------------------------------|--------------------|
|                       ptr_to_lock_record:62                         | lock:2 | Lightweight Locked |
|------------------------------------------------------------------------------|--------------------|
|                 ptr_to_heavyweight_monitor:62                       | lock:2 | Heavyweight Locked |
|------------------------------------------------------------------------------|--------------------|
|                                                                     | lock:2 |    Marked for GC   |
|------------------------------------------------------------------------------|--------------------|

各字段说明:

  • lock (2位):锁状态标志位
    • 00:轻量级锁
    • 01:无锁/偏向锁(通过biased_lock区分)
    • 10:重量级锁
    • 11:GC标记
  • biased_lock(1位):是否启用偏向锁
  • age(4位):对象分代年龄(GC时对象存活次数,最大15)
  • identity_hashcode(31位):对象哈希码
  • thread(54/23位):持有偏向锁的线程ID
  • epoch(2位):偏向锁时间戳
  • ptr_to_lock_record(62/30位):指向栈中锁记录的指针
  • ptr_to_heavyweight_monitor(62/30位):指向重量级锁(Monitor)的指针

三、Klass Pointer(类型指针)

指向方法区中的类元数据(Class Metadata),JVM 通过它确定:

  • 对象属于哪个类
  • 类的完整继承结构
  • 方法调用时的动态绑定

在64位系统中:

  • 未开启指针压缩:64位
  • 开启指针压缩(默认):32位

四、对象头大小总结

系统位数 配置 Mark Word Klass Pointer 总头大小
32位 - 32 bit 32 bit 64 bit
64位 关闭指针压缩 64 bit 64 bit 128 bit
64位 开启指针压缩(默认) 64 bit 32 bit 96 bit

五、使用 JOL 工具查看对象头

Java Object Layout (JOL) 是 OpenJDK 提供的分析工具:

java 复制代码
// 添加依赖:org.openjdk.jol:jol-core
public class ObjectHeaderExample {
    public static void main(String[] args) {
        Object obj = new Object();
        System.out.println(ClassLayout.parseInstance(obj).toPrintable());
        
        synchronized (obj) {
            System.out.println(ClassLayout.parseInstance(obj).toPrintable());
        }
    }
}

示例输出(64位系统,指针压缩):

python 复制代码
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00  # Mark Word
      4     4        (object header)                           00 00 00 00  # Mark Word
      8     4        (object header)                           e5 01 00 f8  # Klass Pointer
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

六、对象头的关键作用

  1. 锁实现:支撑 synchronized 的偏向锁、轻量级锁、重量级锁
  2. GC管理:记录分代年龄、GC标记
  3. 对象标识:存储哈希码
  4. 类型系统:通过 Klass Pointer 实现运行时类型检查

理解对象头结构对于分析 Java 内存布局、性能优化和并发问题排查都有重要意义。

相关推荐
程序员爱钓鱼1 天前
Go语言实战案例 — 工具开发篇:实现一个图片批量压缩工具
后端·google·go
ChinaRainbowSea1 天前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
舒一笑1 天前
同步框架与底层消费机制解决方案梳理
后端·程序员
minh_coo1 天前
Spring框架事件驱动架构核心注解之@EventListener
java·后端·spring·架构·intellij-idea
白初&1 天前
SpringBoot后端基础案例
java·spring boot·后端
计算机学姐1 天前
基于Python的旅游数据分析可视化系统【2026最新】
vue.js·后端·python·数据分析·django·flask·旅游
该用户已不存在1 天前
你没有听说过的7个Windows开发必备工具
前端·windows·后端
David爱编程1 天前
深入 Java synchronized 底层:字节码解析与 MonitorEnter 原理全揭秘
java·后端
KimLiu1 天前
LCODER之Python:使用Django搭建服务端
后端·python·django
再学一点就睡1 天前
双 Token 认证机制:从原理到实践的完整实现
前端·javascript·后端