【JVM】面试题-对象的内存布局


对象在堆内存的存储布局,可分为对象头、实例数据和对⻬填充

1、对象头

占 12B,包括对象标记和类型指针。

======= 🌟 青柠来相伴,代码更简单。🌟 =======
📚 本文所有内容,我都整理在了 青柠合集 里。👇
🎯 搜索关注【青柠代码录】,即可查看所有合集文章 ~
======= 🌟 ================== 🌟 =======

对象标记

存储对象⾃身的运⾏时数据,如哈希值、 GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分占8B,称为Mark Word。

Mark Word (64 bits)                                            State
--------------------------------------------------------------------------------
unused:25 | hashcode:31 | age:4 | biased_lock:0 | 01            Normal
--------------------------------------------------------------------------------
thread:54 | epoch:2 | age:4 | biased_lock:1     | 01            Biased
--------------------------------------------------------------------------------
ptr_to_lock_record:62                           | 00            Lightweight Locked
--------------------------------------------------------------------------------
ptr_to_heavyweight_monitor:62                   | 10            Heavyweight Locked
--------------------------------------------------------------------------------
                                                | 11            Marked for GC

对象状态

  • 【无锁状态】:对象哈希值---GC分代年龄---是否是偏向锁---锁标志位
  • 【偏向锁】:偏向线程ID---epoch---GC分代年龄---是否是偏向锁---锁标志位
  • 【轻量级锁】:指向栈中锁记录的指针---锁标志位
  • 【重量级锁】:指向互斥量(重量级锁/monitor)的指针---锁标志
  • 【GC标记】:空

Mark Word 被设计为动态数据结构,以便在极⼩的空间,存储更多数据,根据对象状态,复⽤存储空间。

类型指针

是对象指向它的类型元数据的指针,占 4B。

JVM 通过该指针,来确定对象是哪个类的实例。

说明:如果是数组,还需记录数组的长度

2、实例数据

是对象真正存储的有效信息,即本类对象的实例成员变量,和所有可⻅的⽗类成员变量。

存储顺序会受到虚拟机分配策略参数,和字段在源码中定义顺序的影响。

相同宽度的字段总是被分配到⼀起存放,在满⾜该前提条件的情况下,⽗类中定义的变量,会出现在⼦类之前。

3、对⻬填充

不是必然存在的,也没特别含义,仅起占位符作⽤。

虚拟机的⾃动内存管理系统,要求任何对象的⼤⼩必须是8B的倍数,对象头已被设为 8B 的 1 或 2 倍,如果对象实例数据部分没有对⻬,需要对⻬填充补全。

public class CustomerTest {
    public static void main(String[] args) {
        Customer cust = new Customer();
    }
}
img
img

此处字符串常量池逻辑上属于方法区,hotspot实现在堆空间中

posted @ 2026-05-10 16:04  青柠代码录  阅读(4)  评论(0)    收藏  举报