Native compilation in Quarkus - why it matters

Hello everyone! This is the second post in our series on Quarkus – today we'll talk about native compilation.

Native compilation in Quarkus - why it matters

Quarkus – a Java stack tailored for Kubernetes. While there's still a lot to be done here, we've thoroughly worked on various aspects, including JVM optimization and a number of frameworks. One of the features of Quarkus that has garnered significant interest from developers is its comprehensive seamless approach to turning Java code into executable files for specific operating systems (known as 'native compilation'), similar to C and C++, where such compilation typically occurs at the end of a cycle consisting of building, testing, and deployment.

And while native compilation, as we'll show below, is important, it should be noted that Quarkus actually runs very well on a standard OpenJDK Hotspot JVM thanks to the performance improvements we've implemented across the stack. Therefore, native compilation should be regarded as an additional bonus that can be used at will or when necessary. In terms of native images, Quarkus significantly relies on OpenJDK. The developer-friendly dev mode is warmly welcomed, providing nearly instantaneous testing of changes due to the advanced dynamic code execution capabilities implemented in Hotspot. Additionally, when creating native images, GraalVM utilizes the OpenJDK class library and HotSpot capabilities.

So why is native compilation needed if everything is already well optimized? This is the question we aim to answer below.

Let's start with the obvious: Red Hat has extensive experience in optimizing JVMs, stacks, and frameworks throughout the development of the JBoss, including:

  • The first application server for cloud use on the Red Hat OpenShift.
  • The first application server for desktop use Plug PC.
  • The first application server for Raspberry Pi.
  • A number of projects operating on devices Android.

We have been addressing the challenges of running Java applications in the cloud and on resource-constrained devices (read, IoT) for many years and have learned to extract the maximum performance and memory optimization from the JVM. Like many others, we have long been working with native compilation of Java applications through GCJ, Avian, Excelsior JET and even Dalvik We are well aware of the advantages and disadvantages of this approach (for instance, the dilemma of choosing between the versatility of 'build once – run anywhere' and the fact that compiled applications have smaller sizes and start faster).

Why is it so important to consider these pros and cons? Because in some situations, their balance becomes decisive:

  • For example, in serverless/event-driven environments, where services must operate in (hard or soft) real-time to respond to events effectively. Unlike long-lived persistent services, here the duration of a cold start critically increases the response time to requests. Starting the JVM still takes a significant amount of time, and although in some cases it can be shortened purely through hardware methods, the difference between one second and five milliseconds can be a matter of life and death. Indeed, one can experiment with creating a hot backup of Java machines (as we did during the porting of OpenWhisk to Knative), but this alone does not guarantee a sufficient number of JVMs to handle requests as the load scales. And from an economic perspective, this is certainly not the most optimal choice.
  • Moreover, there is another frequently surfacing aspect: multi-tenancy. Despite the fact that JVM capabilities have come close to those of operating systems, they still cannot perform a function that we have become so accustomed to in Linux—isolating processes. Therefore, a failure in one thread can take down the entire Java machine. Many try to circumvent this drawback by allocating a separate JVM for each user's applications to minimize the impact of failures. This makes sense, but it does not scale well.
  • Additionally, for cloud-oriented applications, a metric such as service density on the host is vital. Transitioning to the methodology 12 factors of application, microservices and Kubernetes increase the number of Java instances per application. Thus, on one hand, this provides elasticity and reliability, but at the same time, the basic memory consumption per service also rises, with some of these costs not always being strictly necessary. Statically compiled executables gain an advantage here through various optimization techniques, such as low-level dead-code elimination, where only those parts of the frameworks (including the JDK itself) that the service actually uses are included in the final image. Therefore, native compilation with Quarkus helps to place service instances more densely on the host without compromising security.

The arguments presented above are already sufficient to understand the justification for native compilation from the perspective of the Quarkus project participants. However, there is another, non-technical but equally important reason: in recent years, many programmers and development companies have moved away from Java in favor of newer programming languages, considering that Java, along with its JVMs, stacks, and frameworks, has become too memory-hungry, too slow, etc.

However, the habit of using the same tool for solving any task – is not always correct. Sometimes it’s better to take a step back and look for something different. And if Quarkus makes people pause and think, that’s good for the entire Java ecosystem. Quarkus embodies an innovative perspective on how to create more efficient applications, making Java more relevant to new application architectures, such as serverless. Additionally, thanks to its extensibility, Quarkus, as we hope, will develop its own ecosystem of Java extensions, significantly increasing the number of frameworks that will support native compilation out of the box.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster