optimization-zone

Changes that can be made to Java’s configuration and/or parameters to improve application performance. These optimizations are largely unaffected by specific code patterns and as such can be applied in a more generalist manner.

Tuning the JIT compiler: Forcing compilation & Inlining

The C2 JIT compiler is the optimizing compiler of the JDK. We have discovered that some of the default thresholds used for inlining heuristics are not suitable for modern applications which utilize high levels of abstractions (e.g. functional programming style, Stream API, Scala) and deep call stacks.

Therefore, we suggest tuning these threshold using the following JVM options, which should be added to the Java process command line:

java -XX:MaxInlineLevel=40 -XX:TypeProfileMajorReceiverPercent=30 -jar app.jar

In addition, there are thresholds controlling what methods even get compiled by C2: Methods that are too large, even if they are hot, are kept interpreted or compiled at a lower optimization level. This is mostly fine for methods written by humans, but sometimes autogenerated methods get too big and pass the threshold. One such case is Java code generated by the Protobuf compiler (protoc) for de/serializing data: The generated code size is linear in the number of fields in the Protobuf message, so huge Protobuf messages lead to huge Java methods.

To alleviate this issue, we suggest tuning the compilation thresholds using the following JVM options:

java -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=150000 -XX:NodeLimitFudgeFactor=3000 -jar app.jar

Tuning initial heap size

We recommend modifying the initial heap size of all Java processes to match the maximum heap size. This is beneficial for performance as described in the following article: Benefits of setting initial and max memory size.

In short, this prevents frequent memory reallocations which hurt application performance. We suggest doing so by adding the -Xms argument with the same value as the -Xmx. For example, a Java process with -Xmx24g in its command line should be changed to -Xmx24g -Xms24g.