JEP 143: Improve Contended Locking | 改进争用锁定
摘要
改进争用的 Java 对象监视器的性能。
目标
通过以下基准测试和测试,改进争用的 Java 对象监视器的整体性能:
- CallTimerGrid (though more of a stress test than a benchmark)
- Dacapo-bach (was dacapo2009)
- _ avrora
- _ batik
- _ fop
- _ h2
- _ luindex
- _ lusearch
- _ pmd
- _ sunflow
- _ tomcat
- _ tradebeans
- _ tradesoap
- _ xalan
- DerbyContentionModelCounted
- HighContentionSimulator
- LockLoops-JSR166-Doug-Sept2009 (was LockLoops)
- PointBase
- SPECjbb2013-critical (was specjbb2005)
- SPECjbb2013-max
- specjvm2008
- volano29 (was volano2509)
非目标
该项目的目标不是解决内部 VM 监视器或互斥锁的性能改进;Java 监视器和内部 VM 监视器/互斥锁由不同的代码实现。尽管该项目中的一些概念可能适用于内部 VM 监视器/互斥锁,但代码并不直接适用。
该项目的目标不是改进每个基准测试或测试中争用的 Java 监视器的性能;在某些情况下,特定基准测试或测试可能会出现性能下降。为了在另一个基准测试或测试中获得性能改进,可能会认为这种性能下降是可以接受的。
成功指标
如果根据上述基准测试测量到可证明的性能提升,并且没有相应的显著性能回退,那么该项目将被视为成功。
非争用锁的性能不得出现重大回退。
动机
改进争用锁将显著有益于实际应用程序,除了 Volano 和 DaCapo 等行业基准测试。
描述
该项目将探索与争用的 Java 监视器相关的以下领域的性能改进:
- 字段重新排序和缓存行对齐
- 加速
PlatformEvent::unpark()
- 快速的 Java 监视器进入操作
- 快速的 Java 监视器退出操作
- 快速的 Java 监视器
notify
/notifyAll
操作
原始工作的范围还包括“更快的哈希码”;由于 Java 对象哈希码支持与争用的 Java 监视器没有直接关系,因此该工作不包含在此项目中。
该项目还将针对在工作过程中发现的各种错误生成修复程序;这些错误修复将独立于性能改进工作进行管理,以便更早地集成修复程序。
该项目由以下“总体”错误覆盖,以简化管理:
JDK-6607129 减少争用锁自旋循环中的 L2$ 一致性失效流量,特别是对于 ctn-family 上的 derby
然而,随着子任务或错误修复的完成,工作将使用单独的错误 ID 进行集成。这样可以通过一个错误 ID(JDK-6607129)引用整个项目,同时允许增量改进更快地提供,而不必等待整个项目完成。
测试
功能测试
似乎没有专门针对 Java 监视器的功能测试集,也没有必要。Java 监视器被如此广泛地用于甚至最简单的 Java 程序,以至于几乎任何 Java 监视器的功能故障都应该是显而易见的。
压力测试
需要一组针对 Java 监视器的良好的压力测试。这些可以是针对特定 Java 监视器场景的有针对性的压力测试,或者是已知对 Java 监视器使用较多的测试,以特定的压力诱导选项运行。
注意:使用 “-XX:-UseBiasedLocking -XX:+UseHeavyMonitors”
来绕过偏向锁定和基于栈的锁定;强制使用 ObjectMonitor
对象。
字段重新排序和缓存行对齐子任务压力测试
压力测试应该专注于生成大量活动的 ObjectMonitor
对象。压力测试的目标是 ObjectMonitor
的峰值使用情况、ObjectMonitor
块分配算法和 ObjectMonitor
空闲列表管理代码。以下是目标:
- 对于小型到中型配置,具有相同或更好的
ObjectMonitor
峰值使用情况, - 没有内存泄漏,和
- 没有数据结构管理故障。
加速 PlatformEvent::unpark()
子任务压力测试
压力测试应该专注于高并发等待者和/或并发进入 - 退出线程的大量数量。进入 - 等待 - 退出和进入 - 退出线程的混合应该是可配置的。压力测试的目标是后继机制。
目标:没有因为丢失的 unpark 操作而导致挂起。
快速的 Java 监视器进入操作子任务压力测试
压力测试应该专注于具有可扩展数量的并行线程的进入 - 退出操作的正确性。压力测试的目标是 Java 监视器的所有权。
目标:没有所有权冲突,即多个线程认为自己拥有 Java 监视器。
快速的 Java 监视器退出操作子任务压力测试
应该由 “加速 PlatformEvent::unpark()
” 和 “快速的 Java 监视器进入操作” 子任务的压力测试覆盖。
快速的 Java 监视器 Notify/NotifyAll 操作子任务压力测试
压力测试应该专注于具有可扩展数量的并行线程的进入 - 等待 - 退出操作的正确性。压力测试的目标是 Java 监视器在 wait()
完成并重新进入 Java 监视器后的所有权。
目标:没有所有权冲突,即多个线程认为自己拥有 Java 监视器。