彻底理解Java对象头

对象头介绍

Java每个对象都包含两个部分, 对象头(Object Header)对象体(Object Body). 对象头中存储代表该对象运行时的一些信息, 这部分信息与对象体的内容没有关系.

对象头被分为两个部分, 第一个部分是Mark Word, 代表标记信息, 例如hash code, 锁的标志位, GC分代年龄等; 第二个部分是Class Word, 代表类型信息, 该部分是一个指针, 指向方法区(元数据空间) 中的实际类型.

在32位虚拟机中, 对象头占64位, 其中Mark WordClass Word各占32位. 而在64位虚拟机中, 不开启指针压缩的情况下对象头占128位, Mark WordClass Word各占64位. 开启指针压缩之后, Class Word占32位, 对象头减少到占96位.

Mark Word对应到C++的代码marOop.hpp, Class Word对应到C++的代码kclass.hpp
关于文章推荐两篇, 其中一篇是英文, 相对简单, 另一篇是中文, 深入到源码

在这里插入图片描述

对象头详细结构 – 32位虚拟机

在32位的虚拟机中, 对象头的信息如下, 占用64比特(8字节), 数组额外占用4个字节表示长度.
在这里插入图片描述
由于在Mark Word中要存储不同的多种信息, 按照对象状态的不同, 又可以细分为5种状态的Mark Word.

  1. Normal – 普通状态, 由25位哈希码, 4位GC分代年龄, 1位偏向锁标识, 2位锁标志(01)组成.
  2. Biased – 偏向状态, 由23位线程标识, 2位时间戳, 4位GC分代年龄. 1位偏向锁标识, 2位锁标识(01)组成.
  3. Lightweight Locked – 轻量级锁状态, 由30位指针(指向锁记录), 2位锁标识(00)组成.
  4. Heavyweight Locked – 重量级锁状态, 由30位指针(指向重量级锁的monitor, monitor是一个数据结构, 会存储其他抢锁的线程), 2位锁标识(10)组成.
  5. Mared for GC – 待GC回收状态, 只有最后2位锁标识(11)有效.

注意Normal State和Biased State的锁标志位都是01, 而是否偏向锁根据 biased_lock 判断.

Normal State

  • hash code 是懒初始化, 它只会在调用 System#identityHashCode(Object) 方法之后被初始化. 在非普通状态下, hash code 将不在Mark Word中存储, 它会被存储到monitor
  • GC分代年龄是一个数字, 如果它超过了 Tenuring-Threshold则会被移到老年代.
  • biased_lock, 如果偏向锁启用, 则该位置是1, 否者是0

Normal State => biased_lock = 0, lock = 01

Biased State

  • thread 是偏向的线程, 对象头中存储的是线程id
  • epoch 是存储在 thread 位置线程的标识.

Biased State => biased_lock = 1, lock = 01

Lightweight State

  • ptr_to_lock_record, 指向锁记录(存储在当前线程的栈帧), 在锁记录中存储了Mark Word的拷贝. 使用CAS更新该30位, 更新成功则表示获取了轻量级锁.

Heavyweight State

  • ptr_to_heavyweight_monitor是一个指针, 指向 monitor.

对象头详细结构 – 64位虚拟机

在64为虚拟机中, 对象头会变为128比特(16字节), 数组额外占用4个字节表示长度.
在这里插入图片描述
在开启指针压缩之后, 对象头 会变为12字节. 数组还是会额外占用4个字节表示长度.
在这里插入图片描述

指针压缩顾名思义, 压缩的部分是指针, 将64位的 Class Word 压缩为 32 位的 Class Word. 缩小了4个字节. 因为对象是存储在堆中, 如果有大量多的小对象存活. 开启指针压缩将会空闲出一块可观的内存来存储其他对象. 但是当堆的容量很大时, 用32位不足以寻址到对象, 则指针压缩会失效.

写在最后的话

理解对象头是为了更好的理解Synchronized, 文中难免有纰漏的地方, 欢迎指正.

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值