Lambda function with GraalVM Native Image - Part 1 Introduction to GraalVM and its native image capabilities

vkazulkin

Vadym Kazulkin

Posted on October 7, 2024

Lambda function with GraalVM Native Image - Part 1 Introduction to GraalVM and its native image capabilities

Introduction

This series is dedicated to developing and deploying GraalVM Native Image on AWS Lambda with Custom Runtime and measuring performance (cold and warm starts) of our Lambda function.
In the first part of the series, I'll give a very brief introduction to the GraalVM capabilities and especially GraalVM Native Image based on the GraalVM official documentation resources. I'll also explain its benefits for the Serverless applications.

GraalVM overview

GraalVM is a high-performance JDK designed to accelerate the execution of applications written in Java and other JVM languages while also providing runtimes for JavaScript, Python, and a number of other popular languages.

GraalVM Architecture

Image description

GraalVM adds an advanced just-in-time (JIT) optimizing compiler, which is written in Java, to the HotSpot Java Virtual Machine.

In addition to running Java and JVM-based languages, GraalVM’s language implementation framework (Truffle) makes it possible to run JavaScript, Ruby, Python, and a number of other popular languages on the JVM. With GraalVM Truffle, Java and other supported languages can directly interoperate with each other and pass data back and forth in the same memory space.

GraalVM offers two ways to run Java applications: on the HotSpot JVM with Graal just-in-time (JIT) compiler or as an ahead-of-time (AOT) compiled native executable (which will be our focus for the Serverless applications).

Here is the comparison of those both ways to run Java applications:

Image description

GraalVM’s polyglot capabilities make it possible to mix multiple programming languages in a single application while eliminating foreign language call costs.

GraalVM compiles your Java applications ahead of time into standalone binaries. These binaries are smaller, start up to 100x faster, provide peak performance with no warmup, and use less memory and CPU than applications running on a Java Virtual Machine (JVM).

GraalVM reduces the attack surface of your application. It excludes unused classes, methods, and fields from the application binary. It restricts reflection and other dynamic Java language features to build time only. It does not load any unknown code at run time.

Popular microservices frameworks such as Spring Boot, Micronaut, Helidon, and Quarkus, and cloud platforms such as Oracle Cloud Infrastructure, Amazon Web Services, Google Cloud Platform, and Microsoft Azure all support GraalVM.

With profile-guided optimization and the G1 (Garbage-First) garbage collector, you can get lower latency and on-par or better peak performance and throughput compared to applications running on a Java Virtual Machine (JVM).

You can use the GraalVM JDK just like any other Java Development Kit in your IDE.

Introduction to GraalVM Native Image

Native Image is a technology to compile Java code ahead-of-time to a binary – a native executable. A native executable includes only the code required at run time, that is the application classes, standard-library classes, the language runtime, and statically-linked native code from the JDK.

An executable file produced by Native Image has several important advantages, in that it

  • Uses a fraction of the resources required by the Java Virtual Machine, so is cheaper to run
  • Starts in milliseconds
  • Delivers peak performance immediately, with no warmup
  • Can be packaged into a lightweight container image for fast and efficient deployment
  • Presents a reduced attack surface

A native executable is created by the Native Image builder or native image that processes your application classes and other metadata to create a binary for a specific operating system and architecture. First, the native-image tool performs static analysis of your code to determine the classes and methods that are reachable when your application runs. Second, it compiles classes, methods, and resources into a binary. This entire process is called build time to clearly distinguish it from the compilation of Java source code to bytecode.

The native-image tool can be used to build a native executable, which is the default, or a native shared library.

You also have to pay attention to the Reflection in Native Image .

As our applications include many dependencies to the open-source projects, frameworks and libraries we have to be sure that those are ready and tested for GraalVM Native Image. You can find the full list of such projects, frameworks and libraries here.

Install Native Image

Installation instructions of the GraalVM Native Image can be found here.

This is how GraalVM ahead-of-time (AOT) compiled native executable/image (which will be our focus for the Serverless applications) works in detail:

Image description

Conclusion

In the first part of the series, I gave an introduction to the GraalVM and especially its Native Image capabilities. I also explained its benefits for the Serverless applications. In the next part of the series I'll explain how to develop and deploy AWS Lambda function with custom runtime containing GraalVM Native Image.

Sources:

💖 💪 🙅 🚩
vkazulkin
Vadym Kazulkin

Posted on October 7, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related