JVM锁优化

栏目: Java · 发布时间: 5年前

内容简介:锁优化技术(HotSpot虚拟机而言)包括适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁等。这些技术都是为了在线程之间更高效地共享数据以及解决竞争问题,从而提高程序效率。如果线程获取不到锁,第一时间不是去切换系统态进行等待,而是做一个循环操作,去等到锁的释放,循环到一定的次数终止循环,调入系统调用。为了让线程等待,而不是阻塞,让线程执行一个忙循环(自旋),这就是自旋锁。自旋锁的优化主要是为了减少了线程切换带来的消耗。

锁优化技术(HotSpot虚拟机而言)包括适应性自旋、锁消除、锁粗化、轻量级锁和偏向锁等。这些技术都是为了在线程之间更高效地共享数据以及解决竞争问题,从而提高程序效率。

自旋锁

什么是自旋锁?

如果线程获取不到锁,第一时间不是去切换系统态进行等待,而是做一个循环操作,去等到锁的释放,循环到一定的次数终止循环,调入系统调用。为了让线程等待,而不是阻塞,让线程执行一个忙循环(自旋),这就是自旋锁。

为什么消耗CPU而不是等待?

自旋锁的优化主要是为了减少了线程切换带来的消耗。

自旋锁适应的场景

自旋锁适合那些线程占用锁时间短的场景。

什么是自适应自旋锁?

JDK1.6加入了自适应自旋锁。顾名思义,如果在同一个锁对象上,自旋等待刚刚成功获得过锁,并且持有锁的线程正在运行,那么虚拟机就会认为这次自旋也很有可能再次成功,并将自旋等待时间延长。如果对于某个锁,自旋很少成功,那么在之后获取该锁时可能会放弃不自旋直接挂起线程。

锁消除

什么是锁消除?

指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争时,把锁进行消除。

怎样判断哪些代码可以进行锁消除?

锁消除的主要判断依据来源于逃逸分析的数据支持,如果判断在一段代码中,堆上的所有数据都不会逃逸出去从而被其他线程访问到,那就可以把它们当做栈上数据对待,认为它们是线程私有的,同步加锁就无需进行。

锁粗话

什么是锁粗话?

如果一系列的连续动作都对同一对象反复加锁和解锁,甚至加锁操作时出现在循环体中的,那即使没有线程竞争,频繁地进行互斥同步操作也会导致不必要的性能损耗,比如连续的append()方法。

轻量级锁和偏向锁

在说轻量级锁和偏向锁之前,我们要先了解一下HotSpot虚拟机中对象的对象头。

HotSpot虚拟机的对象头分为两部分信息:

  • 第一部分用域存储对象自身的运行时数据(Mark Word),如哈希码、GC分代年龄等,他是实现轻量级锁和偏向锁的关键。
  • 另一部分用于存储只想方法区对象类型的指针,如果是数组对象,还有一个额外部分存储数组长度。

所以,我们来看一下对象头的Mark Word中的存储内容有哪些?

存储内容 标志位 状态 用处
对象哈希码,对象分代年龄 01 未锁定 状态
指向锁记录的指针 00 轻量级锁定 状态
指向重量级锁的指针 10 膨胀 状态
空,不需要记录信息 11 GC标记 状态
偏向线程ID,偏向时间戳、对象分代年龄 01 可偏向 状态

什么是CAS操作?

CAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。简单来说,CAS整个比较并替换的操作是一个原子操作。

轻量级锁

什么是轻量级锁?

他的意思是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的消耗

轻量级锁的执行过程?

加锁过程:

  • 进入同步块的时候,如果此同步对象没有被锁定(锁标志位为“01”状态),虚拟机首先将在当前线程的帧栈中建立一个名为“锁空间”(Lock Record)的空间,用于存储锁对象目前Mark Word的拷贝(这份拷贝叫Displaced Mark Word)
  • 虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针
    • 如果成功,这个线程就有了该对象的轻量级锁,Mark Word的锁标志位变为“00”
    • 如果失败,虚拟机先检查对象的Mark Word是否指向当前线程的栈帧
      • 如果指向当前线程帧栈就说明该线程获取到了该锁,可进入同步块继续执行
      • 若没指向当前线程的帧栈,表示这个锁对象被其他线程占用,这时轻量级锁不再有效,要膨胀为重量级锁,锁的标志位变为“10”,Mark Word 中存储的就是指向重量级锁(互斥量)的指针,后面等待的线程也要进入阻塞状态

解锁过程:

  • 如果对象的Mark Word仍然指向线程的锁记录,就用CAS操作把对象当前Mark Word和线程中复制的Displaced Mark Word替换回来
    • 替换成功,同步完成
    • 替换失败,有其他线程尝试获取该锁,释放锁的同时,唤醒被挂起的线程。

轻量级锁的使用场景

提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”。

如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销。

但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。

偏向锁

什么是偏向锁?

消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。简单来说就是**在无竞争的情况下把整个同步都消除掉,连CAS操作都不做。**就是说当一个线程率先获取到这个锁后,如果该锁没有被其他线程获取,那么持有偏向锁的线程将永远不需要同步。

工作过程

  • 当锁对象 第一次 被线程获取的时候,虚拟机将会把对象头中的标志位设为"01",使用CAS操作把获取到的锁的线程ID记录到Mark Word中,如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,都不再进行任何操作
  • 当有另一个线程去尝试获取这个锁时,偏向模式宣告结束。根据锁对象目前是否处于被锁定的状态,撤销偏向后恢复到未锁定或轻量级锁定的状态,后续的同步操作就如上面介绍的轻量级锁那样执行

偏向锁的使用场景

可以提高带有同步但无竞争的程序性能

和轻量级锁一样,如果这个同步块可能很多时候都是多个线程同时访问的话,那么偏向锁甚至会增加时耗

总结

JVM对锁进行了优化,包括自旋锁(自适应自旋锁)、锁粗化、轻量级锁、偏向锁。而后两者会因为竞争的多少而产生性能的变化。


以上所述就是小编给大家介绍的《JVM锁优化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Design Handbook

Web Design Handbook

Baeck, Philippe de 编 / 2009-12 / $ 22.54

This non-technical book brings together contemporary web design's latest and most original creative examples in the areas of services, media, blogs, contacts, links and jobs. It also traces the latest......一起来看看 《Web Design Handbook》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具