java对象的内存结构

java对象的内存结构

对象结构

在这里插入图片描述

如上图,java对象内存构成分成三部分,对象头、对象体、字节对齐。其中对象头包括:mark word(标记字)、class pointer(类对象指针)、array length(数组长度)

对象头

  1. mark word

    用来存储自身运行时的数据,例如:对象的分代年龄、hashCode、锁状态等信息

  2. Class Pointer(类对象指针)

    用来存储方法区中字节码对象的地址,JVM通过这个指针来确定这个对象是属于那个类的实例。

  3. Array Length(数组长度)

    如果对象是数组,则该字段记录数组的长度,如果不是数组,该字段不存在。是一个可选字段

对象体

对象的成员属性,也包括父类的成员属性,这部分按4字节对齐

字节对齐

对齐字节也叫作填充对齐,其作用是用来保证Java对象所占内存字节数为8的倍数HotSpot VM的内存管理要求对象起始地址必须是8字节的整数倍。对象头本身是8的倍数,当对象的实例变量数据不是8的倍数时,便需要填充数据来保证8字节的对齐

markWord的结构信息

java内置锁的很多信息都存放在对象的mark word字段中。

java内置锁

java有四种内置锁,级别由低到高以此为:无锁、偏向锁、轻量级锁、重量级锁。

在JDK1.6之前,java的锁一直用的重量级锁(重量级锁用的是操作系统底层的锁),但是很多共享资源的操作其实很快就运行完了,比如自增操作,而且一些共享资源往往只有一个线程访问,那么在这些情况下直接使用重量级锁,获取跟释放锁的效率就比较低,因为会设计用户态跟内核态的切换,两者的切换就会比较消耗资源。

所以对synchronized进行了优化,引入了偏向锁、轻量级锁。当然轻量级锁有自适应自旋锁的说法,这个不再讨论范围。

java内置的四种锁状态(无锁、偏向锁、轻量级锁、重量级锁)随着竞争的激烈而逐渐升级,而且是不可逆的,也就是说只能进行锁升级而不可降级。

markWord的结构信息

32位的Mark Word与64位的Mark Word结构相似,以64位的为例。

在这里插入图片描述

上图表示不同锁状态下的64位mark word的结构信息

  1. lock

    锁状态标记位,占两个二进制位,由于希望用尽可能少的二进制位表示尽可能多的信息,因此设置了lock标记。该标记的值不同,整个Mark Word表示的含义就不同

  2. biased_lock

    对象是否启用偏向锁标记,只占1个二进制位。为1时表示对象启用偏向锁,为0时表示对象没有偏向锁

  3. 分代年龄(age)

    4位的Java对象分代年龄。在GC中,对象在Survivor区复制一次,年龄就增加1。当对象达到设定的阈值时,将会晋升到老年代。默认情况下,并行GC的年龄阈值为15,并发GC的年龄阈值为6。由于age只有4位,因此最大值为15,这就是-XX:MaxTenuringThreshold选项最大值为15的原因

  4. 对象hashCode(identity_hashcode)

    31位的对象标识HashCode(哈希码)采用延迟加载技术,当调用Object.hashCode()方法或者System.identityHashCode()方法计算对象的HashCode后,其结果将被写到该对象头中。当对象被锁定时,该值会移动到Monitor(监视器)中

  5. 线程ID(threadId)

    54位的线程ID值为持有偏向锁的线程ID

  6. epoch

    偏向时间戳

  7. ptr_to_lock_record

    占62位,在轻量级锁的状态下指向栈帧中锁记录的指针

  8. ptr_to_heavyweight_monitor

    占62位,在重量级锁的状态下指向对象监视器的指针

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值