跳转到内容

JEP 374:禁用并弃用偏向锁

原文:https://openjdk.org/jeps/374
翻译:张欢

默认禁用偏向锁,并弃用所有相关的命令行选项。

目标

确定是否需要继续支持偏向锁定的遗留同步优化,这种维护成本很高。

动机

偏向锁是HotSpot虚拟机中使用的一种优化技术,用于减少无竞争锁定的开销。它旨在避免在获取monitor时执行CAS原子操作,具体方式是假设monitor一直归给定线程所有,直到不同的线程尝试获取它。monitor的初始锁使monitor偏向该线程,从而避免在对同一对象的后续同步操作中需要原子指令。当很多线程对以单线程方式使用的对象执行很多同步操作时,与普通锁的技术相比,偏向锁通常会导致明显的性能改进。

在过去所看到的提升,在今天远没有那么明显了。很多从偏向锁中受益的应用,都是使用早期Java集合API的陈旧的遗留程序,也就是在每次访问时进行同步(例如HashtableVector)。较新的应用通常使用Java 1.2中为单线程场景引入的非同步集合(例如HashMapArrayList),或者使用Java 5中引入的性能更高的并发数据结构,多用于多线程场景。这意味着,如果更新代码以使用这些较新的类,那些由于不必要的同步而受益于偏向锁的应用可能会看到性能改善。此外,围绕线程池队列和工作线程构建的应用通常在禁用偏向锁的情况下性能更好。(SPECjbb2015就是这样设计的,等等,然而SPECjvm98和SPECjbb2005却不是。)偏向锁带来了在竞争下需要昂贵的撤销操作的成本。因此,受益的只有那些表现出大量无竞争同步操作的应用,如上述那些,因此执行廉价的锁持有者检查加上偶尔的昂贵撤销成本,仍然低于执行避免CAS原子指令的成本。自从将偏向锁定引入HotSpot以来,原子指令成本的变化也改变了该关系保持真实所需的无竞争操作的数量。另一个值得注意的方面是,即使在之前的成本关系是正确的情况下,当花费在同步操作上的时间仍然只占整个应用工作负载的一小部分时,应用也不会从偏向锁定中获得明显的性能改进。

偏向锁定在同步子系统中引入了大量复杂的代码,并且对其他HotSpot组件也有侵入性。这种复杂性是理解代码各个部分的障碍,也是在同步子系统内进行重大设计更改的障碍。为此,我们希望禁用、弃用并最终删除对偏向锁定的支持。

描述

在JDK 15之前,偏向锁始终处于启用和可用的状态。使用本JEP,除非在命令行上设置-XX:+UseBiasedLocking,否则在启动HotSpot时将不再启用偏向锁。

我们将弃用UseBiasedLocking选项,以及与偏向锁的配置和使用相关的所有选项。

  • 生产选项:BiasedLockingStartupDelayBiasedLockingBulkRebiasThresholdBiasedLockingBulkRevokeThresholdBiasedLockingDecayTimeUseOptoBiasInlining
  • 诊断选项:PrintBiasedLockingStatisticsPrintPreciseBiasedLockingStatistics

这些选项仍将被接受并会生效,但将发出弃用警告。

风险和假设

某些Java应用可能会在禁用偏向锁的情况下看到性能下降。允许在命令行上重新启用偏向锁有助于缓解这种情况,并提供可能的洞察力,了解哪些情况仍然可以从其使用中受益。