Sustainable Java Applications With Quick Warmup
Java application startup and warmup technically include several consecutive processes: JVM startup, application startup, and JVM warmup.
Join the DZone community and get the full member experience.
Join For FreeThe slow Java startup problem is notorious in the Java community, but the meaning can confuse the observer. The slow startup problem relates to the process of starting a set of interconnected applications on complex Java frameworks. This process includes starting several applications in Spring Boot, and each of them takes around 10 seconds. So the start of such production as a whole will take a minute, but the start of a JVM in this set is 50 milliseconds. The widespread meaning of slow Java startup referred to this process is not exactly true, as technically this is not a Java problem, but a problem of the framework.
The effect of slow start-up and warm-up is caused by complex frameworks that we use and dynamic features in the runtime. Java is unique in its functionalities, and thanks to its coding and ecosystem power, Java is very popular among enterprises. The same complexity, though, can make it clumsy in the cloud.
Java application startup and warmup technically include several consecutive processes: JVM startup, application startup, and JVM warmup. In these processes, the JVM gets extra time to provide application peak performance.
The warmup phase is taken by JVM to compile and optimize the code. This process is needed for code interpretation and optimization and lasts substantially longer than the startup in cases of large complex applications, taking up to several minutes.
Every time you start your program, these processes begin from scratch. In practice, it means that we spend time running the application and use significant CPU and memory resources to ensure its performance at the startup point. Therefore, the slow startup and warmup leads to extra resources spent for the phase preparing the application to run rather than the resources that might be required for its operation.
Consequently, with the slow startup and warmup, you get increased cloud costs and resource over utilization.
Search for the Solutions
There are several ways to deal with the issue.
- Native Image: has the power to reduce the startup time of Java applications. It uses a different AOT compiler that often provides better performance. Native images use a "closed-world assumption" approach, where by definition, its compiler removes the warmup phase. Native images contain both code and data as a pre-initialized heap created by running user-defined static initializers. The native image snapshot mechanism records only core library classes and user-defined static initialization code. The specific advantage of this method allows the native images to be kept at the same deployment size. When planning on native image implementation, the Native Image compatibility guide should be consulted to ensure it works for your particular application, as not all Java applications can take advantage of this approach.
- Project Leyden: its primary goal is to "improve the startup time, time to peak performance, and footprint of Java programs." This project still needs to be completed, and we cannot yet evaluate the effect and possible difficulties of adaptation. However, among all, the Leyden project is designed to solve the problem of slow startup and we follow the news with great expectations on results.
- Coordinated Restore at Checkpoint: is an OpenJDK project entirely focused on Java startup enhancement. The project's primary aim is to develop a new standard mechanism-agnostic API to notify Java programs about the checkpoint and restore events. Coordinated Restore at Checkpoint (CRaC) offers a Checkpoint/Restore API mechanism solution allowing the creation of an image of a running application at an arbitrary point in time ("checkpoint") and then starting the image from the checkpoint file (snapshot). CRaC snapshots ("checkpoints") include the entire state of the HotSpot process at a specific point in time. The application's state is then restored to where the checkpoint was created and execution continues. Using the CRaC feature with Java runtime in addition gives the option to distribute numerous replicas of the snapshot, which is especially relevant for deployment on multiple instances. Using CRaC to reduce application though requires some modifications to the CI/CD environment, and the optimal choice of the checkpoint moment may not be easy.
- Amazon Lambda: A standalone product based on CRaC technology. Lambda runs your code on a high-availability compute infrastructure and performs all of the administration of the compute resources, including server and operating system maintenance, capacity provisioning, automatic scaling, and logging. Lambdas can be very convenient for your development goals, but they are also more expensive and less effective, compared to the JVMs.
- Java optimization: Migrating to a newer long-term release (LTS) version of Java can improve application performance slightly, bringing minor changes. Such optimization is a quick method, available immediately.
The Effectiveness and Your Runtime Sustainability
The slow startup problem impacts the overall performance of your runtime, and to make your application sustainable and performant, you need to use one of these solutions.
Among the above-mentioned technologies, Native Image is the most adopted in the Java community and is specifically useful for Spring users to achieve faster startup of their applications. It’s been around for quite some time, and it can lead to increased performance, allow programs to run in less memory, and not require a standalone JDK for deployment.
Most frameworks support GraalVM, and the migration to GraalVM is straightforward. At the same time, due to the closed-world assumption, GraalVM may require individual research given the specifics of your Java application, and it will not always be suitable for resolving the startup issue.
The CRaC solution carries many expectations of the Java community. CRaC, just like Project Leyden, is targeted to solve the issue of slow startup. Today you can get OpenJDK runtime and even containers that support the CRaC API. These solutions are ready to install and allow immediate significant improvements. OpenJDK runtimes and small containers with CRaC support possess a high value for Spring developers as Spring announced CRaC feature support in 2023.
The key CRaC advantage is its ease of use, combined with an instant effect on the application performance and cloud costs. OpenJDK runtime with support for Coordinated Restore at Checkpoint advances your application with a feature to quickly create and restore images of a running application, reducing the startup and warmup times from minutes to milliseconds. Enhancing your application with Linux-based containers supported with CRaC strengthens its performance even further. CRaC lowers the load on the processor and memory at the application startup, reducing the cloud costs and improving application performance and sustainability.
We cannot evaluate and test the Leyden results fully yet. The project introduced Class Data Sharing + AOT on steroids, which looks very promising for synergy with Java capable of delivering faster startup on JVM. However, there are no ready-made solutions that can be deployed with Java yet.
In the case of Amazon Lambdas, you should consider the costs of this product and its effectiveness, as it might ultimately deliver an extra financial burden. Its main advantage is convenience.
As a conclusion to this opinion piece, I want to emphasize the vastness of today's Java ecosystem and the various ways the Java community offers to deal with a single issue of the Java startup in complex workloads. The choice of ready-made tools depends on your application requirements, but surely enough, there is more than one method out there to make your Java both cloud-native and sustainable. Your Java journey is always complete with the right vendor capable of delivering all the depth of those offerings for your development routine.
Opinions expressed by DZone contributors are their own.
Comments