Java 中对象的内存布局:Mark Word、Klass Pointer 与实例数据的占比分析

Java 对象内存布局分析

在 HotSpot 虚拟机中,Java 对象的内存布局由三部分组成:对象头(Header)实例数据(Instance Data)对齐填充(Padding)。其中对象头包含 Mark Word 和 Klass Pointer,具体占比取决于系统架构和 JVM 配置(以 64 位系统为例):

1. 对象头 (Header)
  • Mark Word(8 字节)
    存储对象运行时数据:
    $$ \text{哈希码} + \text{GC 年龄} + \text{锁状态} + \text{偏向信息} $$
  • Klass Pointer(4 字节)
    指向类元数据的指针(开启指针压缩时):
    $$ \text{KlassPtr} \rightarrow \text{方法区中的类结构} $$
2. 实例数据 (Instance Data)

存储对象字段值,大小由字段类型决定:

  • 基本类型:$ \text{int} = 4\text{B}, \text{long} = 8\text{B} $
  • 引用类型:$ 4\text{B} $(指针压缩时)
3. 对齐填充 (Padding)

确保对象总大小为 8 字节的整数倍,满足 CPU 内存对齐要求。


占比计算(64 位系统 + 指针压缩)

假设对象含以下字段:

class Example {
    int a;      // 4B
    long b;     // 8B
    String c;   // 4B (引用)
}

组件大小计算实际大小总占比
对象头Mark Word + Klass Ptr12B33.3%
实例数据$4 + 8 + 4$16B44.4%
对齐填充补足 $12+16=28$ → 324B11.1%
总计-32B100%

$$ \text{总大小} = 32\text{B} \quad \left( \frac{\text{对象头}}{32} \times 100% \approx 37.5% \right) $$


关键影响因素

  1. 指针压缩-XX:+UseCompressedOops

    • 开启时:Klass Pointer = 4B,引用 = 4B
    • 关闭时:Klass Pointer = 8B,引用 = 8B
      (关闭后对象头占比升至 ≈50%)
  2. 字段类型优化
    字段重排序可减少内存间隙:

    // 优化前:int(4) + long(8) → 可能产生4B间隙
    // 优化后:long(8) + int(4) → 无间隙
    

  3. 对象对齐规则
    内存分配满足 $ \text{size} \mod 8 = 0 $,否则自动填充。


验证代码

使用 JOL 工具查看实际布局:

// 添加依赖:org.openjdk.jol:jol-core
public static void main(String[] args) {
    System.out.println(ClassLayout.parseClass(Example.class).toPrintable());
}

输出示例:

Example object internals:
OFFSET  SIZE   TYPE DESCRIPTION
0     12        (object header)  // Mark+Klass
12     4    int Example.a
16     8   long Example.b
24     4 String Example.c
28     4        (alignment)      // Padding

验证总大小:$12 + 4 + 8 + 4 + 4 = 32\text{B}$

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值