码迷,mamicode.com
首页 > 编程语言 > 详细

java对象内存布局

时间:2019-01-12 19:03:42      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:art   自身   add   信息   官方   指针   一个   替换   空间   

在 HotSpot 虚拟机中,对象在内存中存储布局分为 3 块区域:对象头(Header)、实例数据(Instance Data)、对齐填充(Padding)。

对象头

HotSpot虚拟机对象的对象头一般包含两部分信息,第一部分用于存储对象自身的运行时数据,例如HashCodeGC分代年龄、锁状态标志、线程持有锁、偏向线程ID、偏向时间戳等信息。官方称这部分数据为Mark Word。在32位和64位的JVM中,这部分数据分别为32bit64bit。

另一部分用于存储对象的类型指针,该指针指向它的类元数据,JVM通过这个指针确定对象是哪个类的实例。在32JVM中,指针的长度为32bit,在未开启压缩指针的64JVM中,该指针的长度为64bit,如果开启压缩指针,那么为32bit

之前提到对象头一般包含两部分信息,这是因为如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,并且这部分数据也随着JVM位数的不同而不同:32位的JVM上,该区域的长度为32bit,在64位未开启压缩指针的JVM中,这部分数据的长度为64bit,否则为32bit

 

 

加锁过程

在代码进入同步块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝(官方把这份拷贝加了一个Displaced前缀,即Displaced Mark Word),这时候线程堆栈与对象头的状态如下图所示。

技术分享图片

然后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针。如果这个更新动作成功,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位(Mark Word的最后两个Bits)将转变为“00”,即表示此对象处于轻量级锁定状态,这时候线程堆栈与对象头的状态如下图所示。

技术分享图片

如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行,否则说明这个锁对象已经被其他线程抢占了。如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁,锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。

解锁过程

解锁过程也是通过CAS操作来进行的,如果对象的Mark Word仍然指向着线程的锁记录,那就用CAS操作把对象当前的Mark Word和线程中复制的Displaced Mark Word替换回来,如果替换成功,整个同步过程就完成了。如果替换失败,说明有其他线程尝试过获取该锁,那就要在释放锁的同时,唤醒被挂起的线程。

 

参考:JVM中锁优化简介

 

java对象内存布局

标签:art   自身   add   信息   官方   指针   一个   替换   空间   

原文地址:https://www.cnblogs.com/rouqinglangzi/p/10260256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!