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 a 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 WildFly application performance tests as you normally would with the following command line flags on Java 11 (jdk11u):
enabled: -XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0
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 accustomed to tuning WildFly’s thread utilization then running your test with the following scenarios would be of great help too:
thread count ~= hardware core count
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.
The term 'thread count' can refer to a great many things in a WildFly context. For most EE apps that are primarily about handling HTTP requests the most relevant configuration area is the
io subsystem, particularly the
task-max-threads attribute in the IO subsystem’s worker resource.
Reporting the result
Please open a bug on the WildFly JIRA with
[jep374] in the title + your project. e.g.
[jep374] results for acme project crazy panda containing the following information per run in the description:
jvm used: jdk11 hardward-core count: N (if you know) thread configuration information: io subsystem config block from your server config or other relevant threading configuration (if you can) 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 a 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
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
ByteOutputStream. The method
putByte is synchronized. So writing a single byte involves a lock and unlock. Note that method
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 JDK 15 while others argued 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!
My thanks to Max Andersen from whose post on quarkus.io most of the content here was shamelessly copied!