Java程序中的Mark Word

什么是Mark Word?

        Mark Word翻译过来就是对象标记,当我们new出来一个对象实例,这个对象实例是由三部分来组成的,分别是对象头,实例数据和对齐填充,Mark Word就存在于对象头当中。接下来我将会对这三个部分进行一一说明。

对象实例的解读

对象实例分为三个部分为:对象头  实例数据 对齐填充

我们先说明实例数据和对其填充

实例数据和对齐填充

        首先如果我们去创建一个对象,这个对象如果是没有任何信息的空对象,他就会占有16个字节的大小,这16个字节分别是组成对象头的Mark Word占有8个字节,类型指针占有8个字节,一共为16个字节,如果你在idle里面设置了指针压缩,这里的内存分配为Mark Word占8个字节,类型指针占有4个字节,然后对其填充4个字节,让他满足16个字节的大小。这是因为new出来的对象大小必须为8的倍数,当空间占有达不到的时候,对齐填充就会补充这些内存。

        如果我们现在创建一个含有int属性的对象实例,int类型占有4个字节,然后对象头是16个字节,一共20个字节,这个时候对齐填充4个字节,凑成24个字节。

        这就是实例数据和对象填充。

对象头

对象头由Mark Word和类型指针组成

Person p = new Person()

        当我们创建以上的对象,这个对象被创建在堆当中,这个p为对象引用,被创建在栈当中,这个Person就是一个模板,被创建在方法区当中,所有的对象都是由这个模板来进行创建的,此时的类型指针就会在方法区中找到这个模板来指向。

        Mark Word的结构图如下

Mark Word主要用来指示对象是否加锁,锁的类型是什么。

锁分为偏向锁,轻量级锁,重量锁。

偏向锁

        如果进行加锁操作,首先是进入偏向锁,偏向锁是为了让线程竞争的时候获取锁的代价更低,而引入的是指偏向于第一个获得他的线程,当第一次执行完成的时候,线程并不会主动释放偏向锁,等到第二次执行的时候,线程会判断此时持有锁的线程是否是自己,如果是自己就继续往下执行,因为之前就没有释放锁,所以这块也不用重新加锁,很明显这里没有额外开销,性能极高。

轻量级锁(自旋锁)和重量锁

        一旦有第二个线程加入锁竞争,偏向锁就升级为轻量级锁(自旋锁)。这里要明确一下什么是锁竞争:如果多个线程轮流获取一个锁,但是每次获取锁的时候都很顺利,没有发生阻塞,那么就不存在锁竞争。只有当某线程尝试获取锁的时候,发现该锁已经被占用,只能等待其释放,这才发生了锁竞争。

        在轻量级锁状态下继续锁竞争,没有抢到锁的线程将自旋,即不停地循环判断锁是否能够被成功获取。获取锁的操作,其实就是通过CAS修改对象头里的锁标志位。先比较当前锁标志位是否为“释放”,如果是则将其设置为“锁定”,比较并设置是原子性发生的。这就算抢到锁了,然后线程将当前锁的持有者信息修改为自己。

        长时间的自旋操作是非常消耗资源的,一个线程持有锁,其他线程就只能在原地空耗CPU,执行不了任何有效的任务,这种现象叫做忙等(busy-waiting)。如果多个线程用一个锁,但是没有发生锁竞争,或者发生了很轻微的锁竞争,那么synchronized就用轻量级锁,允许短时间的忙等现象。这是一种折衷的想法,短时间的忙等,换取线程在用户态和内核态之间切换的开销。

        显然,此忙等是有限度的(有个计数器记录自旋次数,默认允许循环10次,可以通过虚拟机参数更改)。如果锁竞争情况严重,某个达到最大自旋次数的线程,会将轻量级锁升级为重量级锁(依然是CAS修改锁标志位,但不修改持有锁的线程ID)。当后续线程尝试获取锁时,发现被占用的锁是重量级锁,则直接将自己挂起(而不是忙等),等待将来被唤醒。

对于上面出现CAS的解读

        什么是CAS呢?

        Compare-and-Swap,即比较并替换,也有叫做Compare-and-Set的,比较并设置

        1、比较:读取到了一个值A,在将其更新为B之前,检查原值是否仍为A(未被其他线程改动)。

        2、设置:如果是,将A更新为B,结束。如果不是,则什么都不做。

        上面的两步操作是原子性的,可以简单地理解为瞬间完成,在CPU看来就是一步操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下水道程序员

你的鼓励将是我奋斗的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值