Biased locking removed from Java - does it affect you ?

Last week we became aware that the OpenJDK team in Java 15 have disabled biased locking (JEP 374) in the Java virtual machine. This is a change from previous versions and could potentially have a negative impact on Java application’s performance.

Red Hat’s own performance teams are currently running performance tests to see how it affects our Java middleware, but no amount of generic testing can reveal how this change affects real-world applications.

That is where you come in.

We would like to get info from you on whether your application performance is affected by biased locking or not.

To do so please try the following in your application performance tests:

Run your Quarkus application performance tests as you normally would with the following command line flags on Java 11 (jdk11u) and if feasible Java 15 (jdk15):

enabled: -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0

disabled: -XX:-UseBiasedLocking

We would like to know the result of this no matter if you see a regression or not on the same Java Virtual Machine.

If you are able then running it with the following scenarios would be of great help too:

  1. single-threaded

  2. thread count ~= hardware core count

  3. thread count ~= N * hardware core count where 8 < N < 16

The intent of these are to see how the level of concurrency affects the result.

Reporting the result

Please open a bug with [jep374] in the title + your project. i.e. [jep374] results for acme project crazy panda containing the following information per run in the description:

jvm used: jdk11 or jdk15
thread-count: 1..N (if you know)
hardware-core count: N (if you know)
performance test result: with biased locking
performance test result: without biased locking

This will help us immensely. Thank you!


Below is some background context on biased locking - all optional reading - you don’t need to understand the details to help us by running your performance tests and let us know if anything changes.

What is biased locking?

Biased locking lowers the cost of /uncontended/ synchronization.

Without biased locking: a thread needs to set and clear a lock bit when it performs repeated synchronizations on the same object. It also needs to wait for those set/clear writes to be drained to local cache before proceeding to execute further memory operations.

With biased locking: the first time a thread synchronizes on an object it does a bit more work to acquire synchronized ('bias' it to the thread). Subsequent syncrhonizations proceed via a simple read test with no need to drain to cache.

Where’s the trade off? Well, if a biased lock is contended then there is more work to do to bias and unbias the lock. However, it is known that many synchronized operations are uncontended.

Biasing can be big win when a potentially concurrent data structure is actually used sequentially. The case where it helps most is exemplified in the problem we already found in class DataOutputStream. Normally only one thread writes a DataOutputStream and it is often not read until the stream has been filled. All the same, every putInt() or putLong()` call invokes a syncrhonized method to increment the byte count by 4 or 8. That’s needed just in case some other thread might want to reliably locate the end of the valid buffer data but that rarely happens. So, the unbiased case suffers lock write and cache drain delays at every basic put operation.

A similar case occurs with class ByteOutput Stream. Method putByte is synchronized. So writing a single byte involves a lock and unlock. n.b. method putInt calls putByte 4 times, requiring 4 locks and unlocks. Method putLong calls it 8 times!

Why is biased locking being removed?

The implementation of biased locking adds a great deal of complexity to the JVM and is understood by only a small subset of the most experienced engineers. The cost of maintaining it and designing around it is significantly slowing down progress on new features. It has been a long term goal to remove it if at all possible. Some OpenJDK contributors wanted to remove it right away in jdk15 others argue for a slower deprecation route in order to check that we could really dispense with it.

What happens next?

We are collecting our own internal performance tests across multiple teams in Red Hat and will gather data from community reported tests too and see what the data indicates. At this stage we are making no assumption that the removal of biased locking will definitely make performance worse. We know that in some cases not having biased locks will improve performance. Our concern is to find cases, like the JDK examples above, where it might cause serious performance degradation and get an idea of how bad, and also how common, the worst cases might be.

Once processed we might reach out to those reporting scenarios with unexpected results and get more details.

Then we’ll work with the larger OpenJDK community to aid in deciding if biased locking can be turned off completely or a longer graceful deprecation period is needed.

In any case - Thank you for your help and interest in making Java better!