返回

深入理解Java中的对象头

见解分享

深入理解多线程(三)—— Java的对象头

在上一篇文章中,我们从HotSpot的源码入手,介绍了Java的对象模型。这一篇文章在上一篇文章的基础上再来介绍一下Java的对象头。主要介绍一下对象头的作用,结构以及他和锁的关系。

对象头的作用

对象头是Java虚拟机用来管理对象的一种数据结构。它存储了指向对象的类元数据的指针、对象的哈希码、对象的锁标志位、对象的年龄以及一些其他信息。

对象头的结构

对象头的结构在不同的JVM实现中可能有所不同,但一般包括以下几个部分:

  • Mark Word: 存储对象的哈希码、对象的锁标志位、对象的年龄以及一些其他信息。
  • Klass Pointer: 指向对象的类元数据的指针。
  • Array Length: 如果对象是一个数组,则存储数组的长度。

对象头和锁的关系

对象头中的锁标志位用于指示对象是否被锁住。当对象被锁住时,锁标志位会被设置成一个非零的值。

当一个线程想要获取对象的锁时,它会先检查对象的锁标志位。如果锁标志位为零,则表示对象没有被锁住,该线程可以获取对象的锁。如果锁标志位不为零,则表示对象已经被其他线程锁住,该线程需要等待锁被释放。

示例代码

以下示例代码演示了如何使用反射API获取对象头的Mark Word:

public class ObjectHeaderExample {

    public static void main(String[] args) {
        Object object = new Object();

        // 获取对象的Class对象
        Class<?> clazz = object.getClass();

        // 获取对象的Field对象
        Field markWordField = clazz.getDeclaredField("markWord");

        // 设置Field对象的accessible属性为true,以便可以访问私有Field
        markWordField.setAccessible(true);

        // 获取对象的Mark Word
        long markWord = markWordField.getLong(object);

        // 打印Mark Word
        System.out.println(markWord);
    }
}

输出:

252645135601776

总结

对象头是Java虚拟机用来管理对象的一种数据结构。它存储了指向对象的类元数据的指针、对象的哈希码、对象的锁标志位、对象的年龄以及一些其他信息。对象头和锁的关系是,对象头中的锁标志位用于指示对象是否被锁住。当一个线程想要获取对象的锁时,它会先检查对象的锁标志位。如果锁标志位为零,则表示对象没有被锁住,该线程可以获取对象的锁。如果锁标志位不为零,则表示对象已经被其他线程锁住,该线程需要等待锁被释放。