Optimization of Java Applications – CPU Usage, Memory Usage, Startup Time, Resource Efficiency

Question

What possibilities exist to optimize JVM-based applications in terms of CPU usage, memory usage, startup time, resource efficiency, etc.?

How to measure and find bottlenecks?

Framework

Studies:

Quarkus vs. Spring Boot

Quarkus has a much faster startup time and a lower memory usage.

JVM Distribution

How to optimize the runtime efficiency by choosing an optimal JVM distribution?

OpenJ9 vs. HotSpot

OpenJ9 requires less memory than OpenJDK with HotSpot.

Tradeoffs, Bad Science, and Polar Bears – The World of Java Optimisation By Holly Cummins#HotSpot vs. OpenJ9

Vergilio et al. (2023)

@Vergilio.etal.2023.ComparativePerformanceEnergy

vergilio.etal.2023.comparativeperformanceenergy (pg. 23)

Overall, this study has clearly demonstrated that, in most cases, GraalVM-based Java 11 applications provide better performance, consume less energy, and emit less carbon equivalent footprint than those utilising OpenJDK and two other popular JVM distributions in the market (Amazon Corretto and Zulu).

Note: A benchmark suite case was used that focusses on concurrency workloads. The way of how the energy was measured is also questionable (workload inside WSL2, measurement tool on the Windows host system).

Belgaid (2022)

@Belgaid.2022.GreenCoding

belgaid.2022.greencoding (image) (pg. 124)

Figure 5.5: Energy consumption comparison across Java benchmarks for HOTSPOT, GRAALVM & J9.

belgaid.2022.greencoding (pg. 123)

Figure 5.5 further explores the comparison of energy efficiency of the JVM distributions per benchmark. One can observe that, depending on the benchmark’s focus, the energy efficiency of JVM distributions may strongly vary. When considering individual benchmarks, J9 performs the worst for at least 6 out of 12 benchmarks—i.e., the worst ratio among the 4 tested distributions. Even though, J9 can still exhibit a significant energy saving for some benchmarks, such as Avrora, where it consumes 38% less energy than HOTSPOT and others. Interestingly, GRAALVM delivers good results overall, being among the distributions with low energy consumption for all benchmarks, except for Reactors and Avrora. Yet, some differences still can be observed with HOTSPOT depending on applications. The newer version of HOTSPOT-15 was averagely good and, compared to HOTSPOT-8, it significantly enhances energy consumption for most scenarios. Finally, Neo4J is the only selected benchmark where HOTSPOT-8 is more energy efficient than HOTSPOT-15.

Belgaid developed a tool called JReferral that can help to find the most energy-efficient JVM configuration. For that it runs your Java program through multiple versions of JVMs and optimizations options.

Ournani et al. (2021)

Ournani, Z., Belgaid, M. C., Rouvoy, R., Rust, P., & Penhoat, J. (2021, October 11). Evaluating the Impact of Java Virtual Machines on Energy Consumption. 15th ACM/IEEE International Symposium on Empirical Software Engineering and Measurement (ESEM). https://inria.hal.science/hal-03275286

The results of our investigations showed that many JVMs share energy efficiencies and can grouped into 3 classes: HotSpot, J9, and GraalVM. The 3 selected JVM classes can however report a different energy efficiency for different software and/or workloads, sometimes by a large margin. While we did not observed a unique champion when it comes to energy consumption, GraalVM reported the best energy efficiency for a majority of benchmarks. Nonetheless, each JVM can achieve the best or the worst depending on the hosted application.

JVM vs. Native

JVM vs. Native Java Compilation

CRaC, CDS, Project Leyden

Optimization of Java Applications – CPU Usage, Memory Usage, Startup Time, Resource Efficiency-20241025065332759.webp|700

Overview created by Sébastien Deleuze (source: LinkedIn)

AOT cache: JEP 483: Ahead-of-Time Class Loading & Linking

JVM Configuration

Memory

java -XX:MaxRAMPercentage=75 -XX:+UseParallelGC -XX:ActiveProcessorCount=<2x yourCpuLimit> myapp.jar

JVM Kubernetes: Optimizing Kubernetes for Java Developers - Pretius

There is no way to guarantee the complete memory bundary of a Java process since the JVM respects only the heap size limit; not non-heap memory, which will depend on various factors. Start with a 75% ratio of heap to non-heap memory, and keep a close watch on how your memory behaves. If things get out of hand, you can tweak your pod’s memory limits or fiddle with the heap-to-non-heapratio to dodge the OOMKilled mishaps.

Memory settings for Java process running in Kubernetes pod | by Fan Liu | Medium

Deployment Type

Minimize the size of your Docker images

The reference application (Spring-PetClinic 2.1.0) used in the experiments needs only 14 modules from a total of 74 modules that comprise OpenJDK 11. By using the Java Linker (jlink), the Java Runtime Environment was customized for the given Java application (Spring-PetClinic), thus enabling us to minimize the size of the resulting Docker image

Database

Database Performance Optimization

🔗 References

Reduce the cloud bill of your Java applications by Ioannis Kolaxis

How to write greener Java applications by Red Hat (→ use Quarkus)

Tradeoffs, Bad Science, and Polar Bears – The World of Java Optimisation By Holly Cummins