补充之Java对象头

1 什么是Java对象头

  • 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding)。
  • 也就是说 JAVA对象 = 对象头 + 实例数据 + 对齐填充。
  • 其中,对象头由两部分组成,一部分用于存储自身的运行时数据,称之为 Mark Word,另外一部分是类型指针,即对象指向它的类元数据的指针。

对象头 = Mark Word + 类型指针(未开启指针压缩的情况下)

  • 在32位系统中,Mark Word = 4 bytes = 32 bits,对象头 = 8 bytes = 64 bits;
  • 在64位系统中,Mark Word = 8 bytes = 64 bits ,对象头 = 16 bytes = 128bits;

bytes 是字节,bits 是位。所以说,在32位JVM虚拟机系统中,Mark Word部分,占了4个字节,Klass Word部分也占了4个字节,所以,对象头大小为8个字节。在64位JVM虚拟机系统中,Mark Word部分,占了8个字节,Klass Word部分也占了8个字节,所以,对象头大小为16个字节。

2 32位虚拟机对象头

32位虚拟机普通对象的对象头

|-----------------------------------------------------------|
|                    Object Header (64 bits)                |
|---------------------------------|-------------------------|
|             Mark Word (32 bits) | Klass Word (32 bits)    |
|---------------------------------|-------------------------|

64位虚拟机普通对象的对象头

|---------------------------------------------------------------------------------|
|                                  Object Header (96 bits)                        |
|--------------------------------|-----------------------|------------------------|
|       Mark Word(32bits)        | Klass Word(32bits)    | array length(32bits)   |
|--------------------------------|-----------------------|------------------------|

详细状态如下

|-----------------------------------------------------------------------------------------------------------------|
|                                             Object Header(64bits)                                               |
|-----------------------------------------------------------------------------------------------------------------|
|                       Mark Word(32bits)                           |  Klass Word(32bits)    |      State         |
|-----------------------------------------------------------------------------------------------------------------|
|     hashcode:25                      | age:4 | biased_lock:0 | 01 | OOP to metadata object |      Nomal         |
|-----------------------------------------------------------------------------------------------------------------|
|     thread:23              | epoch:2 | age:4 | biased_lock:1 | 01 | OOP to metadata object |      Biased        |
|-----------------------------------------------------------------------------------------------------------------|
|     ptr_to_lock_record:30                                    | 00 | OOP to metadata object | Lightweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|     ptr_to_heavyweight_monitor:30                            | 10 | OOP to metadata object | Heavyweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                                                              | 11 | OOP to metadata object |    Marked for GC   |
|-----------------------------------------------------------------------------------------------------------------|

3 64位虚拟机对象头

|-----------------------------------------------------------------------------------------------------------------|
|                                             Object Header(128bits)                                              |
|-----------------------------------------------------------------------------------------------------------------|
|                                   Mark Word(64bits)               |  Klass Word(64bits)    |      State         |
|-----------------------------------------------------------------------------------------------------------------|
|    unused:25|identity_hashcode:31|unused:1|age:4|biase_lock:0| 01 | OOP to metadata object |      Nomal         |
|-----------------------------------------------------------------------------------------------------------------|
|    thread:54|      epoch:2       |unused:1|age:4|biase_lock:1| 01 | OOP to metadata object |      Biased        |
|-----------------------------------------------------------------------------------------------------------------|
|                        ptr_to_lock_record:62                 | 00 | OOP to metadata object | Lightweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                       ptr_to_heavyweight_monitor:62          | 10 | OOP to metadata object | Heavyweight Locked |
|-----------------------------------------------------------------------------------------------------------------|
|                                                              | 11 | OOP to metadata object |    Marked for GC   |
|-----------------------------------------------------------------------------------------------------------------|

4 对象头信息解释

  • lock:2位的锁状态标记位,由于希望用尽可能少的二进制位表示尽可能多的信息,所以设置了lock标记。该标记的值不同,整个mark word表示的含义不同。
  • biased_lock:对象是否启用偏向锁标记,只占1个二进制位。为1时表示对象启用偏向锁,为0时表示对象没有偏向锁。
biased_lock lock 状态
0 01 无锁
1 01 偏向锁
0 00 轻量级锁
0 10 重量级锁
0 11 GC标记
  • age:4位的Java对象年龄。
  • identity_hashcode:25位的对象标识Hash码
  • thread:持有偏向锁的线程ID。
  • epoch:偏向时间戳。
  • ptr_to_lock_record:指向栈中锁记录的指针。
  • ptr_to_heavyweight_monitor:指向管程Monitor的指针。

5 对象头查看工具

  • 查看对象头,就需要用到借助JOL工具。

    <dependency>
         <groupId>org.openjdk.jol</groupId>
         <artifactId>jol-core</artifactId>
         <version>0.10</version>
    </dependency>
    
  • 代码示例

    @Slf4j
    public class TestBiased {
          
          
    
        public static void main(String[] args) throws InterruptedException {
          
          
            Dog dog = new Dog();
            //查看对象内部信息
            System.out.println(ClassLayout.parseInstance(dog).toPrintable());
            // 此时偏向锁还未生效
            Thread.sleep(4000);
            // 现在生效了
            System.out.println(ClassLayout.parseInstance(new Dog()).toPrintable());
        }
    }
    
    class Dog {
          
          
    }
    
  • 部分打印结果
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36389060/article/details/121721791
今日推荐