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 内存布局、性能优化和并发问题排查都有重要意义。

相关推荐
雷渊13 分钟前
DDD经典的四层架构和洋葱架构、六边形架构区别
后端
SimonKing15 分钟前
【Spring Boot配置终极指南】1分钟让你精准指定配置文件,使应用部署游刃有余!
java·后端
雷渊15 分钟前
深入分析理解洋葱架构
后端
程序媛学姐28 分钟前
SpringBoot Actuator健康检查:自定义HealthIndicator
java·spring boot·后端
程序媛学姐40 分钟前
SpringBoot Actuator指标收集:Micrometer与Prometheus集成
spring boot·后端·prometheus
欲儿1 小时前
RabbitMQ原理及代码示例
java·spring boot·后端·rabbitmq
林 子1 小时前
Spring Boot自动装配原理(源码详细剖析!)
spring boot·后端
编程轨迹1 小时前
使用 Spring 和 Redis 创建处理敏感数据的服务
后端
未完结小说1 小时前
服务注册与发现(nacos)
后端
AI智能科技用户7946329782 小时前
okcc呼叫中心两个sip对接线路外呼任务怎么设置才能一个任务对应yigesip中继?
人工智能·后端