How to disable the spinlock for synchronization in OpenJDK

Viewed 166

Background

I am analyzing a performance issue on a Java servlet running on AdoptOpenJDK 11. The response time of the servlet slows down as the number of concurrent requests increases.

To isolate the cause of the issue, I had collected performance information with two tools while changing the number of concurrent requests:

  • Windows Performance Monitor (to inspect CPU usage of the server)
  • JDK Flight Recorder and JDK Mission Control (to inspect synchronization issue in JavaVM)

Problem

According to Mission Control, the servlet has a synchronization issue. It causes so many synchronization events when two or more requests come concurrently. The synchronization events are fired in a class used to lookup a table. The lookup table is implemented with ConcurrentHashMap. So the synchronization is not intentional and looks unnecessary.

On the other hand, according to the Performance Monitor, the number of concurrent requests and the CPU usage % are almost linearly increase together. This is an unexpected result for me.

I had expected that the CPU usage will become constant because the requests will be processed one by one due to the synchronization. As a result of more research, I have found the Java VM had introduced the Adaptive Spinning on Java 6, and I had set a hypothesis that this (spinlock for synchronization in Java VM) is the reason why the CPU usage increased linearly.

Question

The class that causes the synchronization issue is used in so many places in our application. To reasoning and explanation for the change to the class (remove the synchronized block from the class), I have to confirm the hypothesis with the result of a performance test. To confirm the hypothesis, I want to disable the spinlock for synchronization in Java VM.

I have found the JRockit and OpenJ9 had the command-line option to change the behavior of the adaptive spinning. But I could not find the equivalent for OpenJDK. There were no options related to spinlock in the result of java -XX:+PrintFlagsFinal -version.

Is there any way to disable the spinlock for synchronization in OpenJDK Java VM?

1 Answers

The question is actually an XY problem. I'll answer it with the caveat that the experiment might be useless or even misleading.

The hypothesis that disabled spinning will decrease CPU usage is not necessary correct. Without spinning, a contended lock ends up in calling into OS kernel to park/unpark threads. A system call with a context switch is expensive, so, depending on the number of threads and the length of the critical section, this may actually increase CPU usage.

The options to disable spinning on intrinsic locks in OpenJDK 11 are:

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

However, SyncKnobs have never been found useful, and were completely removed in JDK 12.

Related