Java 如何在OpenJDK中禁用同步的自旋锁 背景

Java 如何在OpenJDK中禁用同步的自旋锁 背景,java,jvm,synchronization,spinlock,Java,Jvm,Synchronization,Spinlock,我正在分析在OpenJDK 11上运行的Java servlet的性能问题。servlet的响应时间随着并发请求数量的增加而减慢 为了找出问题的原因,我在更改并发请求的数量时使用了两个工具收集了性能信息: Windows性能监视器(用于检查服务器的CPU使用情况) JDK飞行记录器和JDK任务控制(检查JavaVM中的同步问题) 问题 根据任务控制,servlet存在同步问题。当两个或多个请求同时出现时,它会导致许多同步事件。同步事件在用于查找表的类中激发。查找表是用ConcurrentHa

我正在分析在OpenJDK 11上运行的Java servlet的性能问题。servlet的响应时间随着并发请求数量的增加而减慢

为了找出问题的原因,我在更改并发请求的数量时使用了两个工具收集了性能信息:

  • Windows性能监视器(用于检查服务器的CPU使用情况)
  • JDK飞行记录器和JDK任务控制(检查JavaVM中的同步问题)
问题 根据任务控制,servlet存在同步问题。当两个或多个请求同时出现时,它会导致许多同步事件。同步事件在用于查找表的类中激发。查找表是用
ConcurrentHashMap
实现的。因此,同步不是有意的,看起来不必要

另一方面,根据性能监视器,并发请求的数量和CPU使用率几乎是线性增加的。这对我来说是一个意想不到的结果

我曾期望CPU使用率将变得恒定,因为由于同步,请求将一个接一个地处理。作为更多研究的结果,我发现JavaVM已经引入,并且我已经设置了一个假设,即这(JavaVM中用于同步的自旋锁)是CPU使用率线性增加的原因

问题: 导致同步问题的类在应用程序中的许多地方都使用。为了对类的更改进行推理和解释(从类中删除
synchronized
块),我必须用性能测试的结果来确认假设。为了证实这一假设,我想在JavaVM中禁用同步的自旋锁

我已经找到了,并使用命令行选项来更改自适应旋转的行为。但是我找不到OpenJDK的等价物。
java-XX:+PrintFlagsFinal-version
的结果中没有与自旋锁相关的选项


有没有办法在OpenJDK Java VM中禁用同步的自旋锁?

这个问题实际上是个问题。我将以警告来回答这个问题,这个实验可能是无用的,甚至是误导性的

禁用旋转将减少CPU使用的假设是不正确的。在不旋转的情况下,争用锁最终会调用操作系统内核来停止/取消线程。带有上下文开关的系统调用代价很高,因此,根据线程的数量和关键部分的长度,这实际上可能会增加CPU的使用

在OpenJDK 11中禁用内在锁旋转的选项有:

-XX:+UnlockExperimentalVMOptions -XX:SyncKnobs=SpinLimit=0:SpinBase=0:PreSpin=0:SpinEarly=0

然而,
SyncKnobs
从未被发现有用,并且出现在JDK 12中。

我正在查看可能的标志,但我看不到任何相关的内容:(除非Pangin以某种方式带来了他的魔法,否则我认为这是不可能的。”…因为由于同步,请求将被逐个处理”框架正在努力防止这种情况发生。你是说你正在试图通过对全局对象执行同步来破坏这些意图,还是你认为你的servlet容器有这样一个同步?如果你想禁用旋转只是为了检查它是否使CPU使用量保持恒定-我可以毫无经验地告诉你nt:不会。要找出CPU时间真正花在哪里,请使用。除了应用程序代码外,它还显示了CPU最密集的JVM和操作系统活动,包括旋转锁等。不幸的是,异步探查器在Windows上不工作,但您可以试着在Linux VM上或在Linux VM中运行应用程序。@apangin我可以确认异步探查器可以es与WSL2一起运行。它只能分析在环境中启动的进程,但对于非UI代码是可行的。这听起来不像是一个会导致请求逐个处理的同步,而是一个可以与其他执行完全重叠的停止和移动。甚至不清楚请求是否使用相同的object以同步。