JEP 374: Deprecate and Disable Biased Locking | 禁用和弃用偏向锁
摘要
默认情况下禁用偏向锁,并弃用所有相关命令行选项。
目标
确定是否需要继续支持偏向锁这一传统的同步优化技术,因为维护该技术成本高昂。
动机
偏向锁是 HotSpot 虚拟机中使用的一种优化技术,用于减少无竞争锁定的开销。它通过假设监视器在被给定线程拥有时不会被其他线程获取,从而在获取监视器时避免执行比较并交换原子操作。 监视器的初始锁将监视器“偏向”于该线程,从而避免了在后续对同一对象的同步操作中需要原子指令。 当许多线程对以单线程方式使用的对象执行许多同步操作时,历史上,偏向锁比常规锁定技术带来了显著的性能提升。
过去所看到的性能提升在今天已不那么明显。许多受益于偏向锁的应用都是较老的传统应用,它们使用了早期的 Java 集合 API,这些 API 会在每次访问时同步(例如 Hashtable
和 Vector
)。新应用通常使用 Java 1.2 中引入的非同步集合(例如 HashMap
和 ArrayList
),这些集合适用于单线程场景,或者 Java 5 中引入的性能更高的并发数据结构,这些数据结构适用于多线程场景。这意味着,如果代码更新为使用这些新类,因不必要的同步而受益于偏向锁的应用可能会看到性能提升。此外,围绕线程池队列和工作线程构建的应用在禁用偏向锁后通常表现更好。(例如,SPECjbb2015 就是这样设计的,而 SPECjvm98 和 SPECjbb2005 则不是)。偏向锁在发生争用时需要执行昂贵的撤销操作。因此,只有那些执行大量无竞争同步操作的应用(如上面提到的那些)才能从中受益,因为执行廉价的锁拥有者检查加上偶尔的昂贵撤销的成本仍然低于执行避免的比较并交换原子指令的成本。自从在 HotSpot 中引入偏向锁以来,原子指令成本的变化也改变了使该关系保持真实所需的无竞争操作的数量。另一个值得注意的方面是,即使当同步操作所花费的时间仍然只是总应用工作负载的一小部分时,即使前面的成本关系为真,应用也不会从偏向锁中获得明显的性能提升。
偏向锁在同步子系统中引入了大量的复杂代码,并对其他 HotSpot 组件造成了侵入。这种复杂性是理解代码各个部分的障碍,也是同步子系统内进行重大设计更改的障碍。因此,我们希望禁用、弃用并最终移除对偏向锁的支持。
说明
在 JDK 15 之前,偏向锁始终启用并可用。通过这项 JEP,除非在命令行上设置了 -XX:+UseBiasedLocking
,否则在启动 HotSpot 时将不再启用偏向锁。
我们将弃用 UseBiasedLocking
选项以及与偏向锁的配置和使用相关的所有选项。
- 产品选项:
BiasedLockingStartupDelay
、BiasedLockingBulkRebiasThreshold
、BiasedLockingBulkRevokeThreshold
、BiasedLockingDecayTime
和UseOptoBiasInlining
- 诊断选项:
PrintBiasedLockingStatistics
和PrintPreciseBiasedLockingStatistics
这些选项仍将被接受并处理,但会发出弃用警告。
风险与假设
禁用偏向锁后,一些 Java 应用程序可能会遇到性能下降。允许在命令行上重新启用偏向锁有助于缓解这种情况,并可能提供关于哪些情况仍可能受益于其使用的见解。