GraalVM Native Image compile Java app thành native executable — không cần JVM lúc chạy.
Build:
<!-- pom.xml -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin># Build native executable (cần GraalVM hoặc Docker)
mvn -Pnative native:compile
# Build native Docker image (không cần cài GraalVM)
mvn -Pnative spring-boot:build-imageKết quả thực tế (số liệu từ Spring team):
| JVM | Native | |
|---|---|---|
| Startup time | ~2-5s | ~50-200ms |
| Memory (RSS) | ~300MB | ~50-80MB |
| Throughput | Cao (JIT) | Thấp hơn ~10-20% |
| Build time | ~30s | 3-10 phút |
Cơ chế — AOT (Ahead-of-Time compilation):
- Spring Boot 3 phân tích app lúc build, sinh reflection metadata.
- Native Image tool compile toàn bộ thành binary.
- Closed-world assumption: tất cả code phải biết trước lúc compile.
Hạn chế phải biết:
- Reflection phải khai báo — Spring tự handle phần lớn, nhưng thư viện bên thứ ba đôi khi cần reflect-config.json.
- Dynamic proxy giới hạn — Spring AOP qua CGLIB có thể gặp vấn đề.
- Classpath scanning không hoạt động lúc runtime.
- Build chậm — CI pipeline cần tính toán thời gian.
Khi nào dùng Native Image:
- Serverless / AWS Lambda — cold start quan trọng.
- CLI tool viết bằng Spring Shell.
- Microservice cần startup nhanh và memory thấp.
Khi nào KHÔNG dùng:
- App cần throughput cao (native kém JIT ~10-20% sau warmup).
- Dùng nhiều thư viện chưa hỗ trợ GraalVM.
- Team không có kinh nghiệm debug native image.
GraalVM Native Image compiles a Java app into a native executable — no JVM required at runtime.
Build:
<!-- pom.xml -->
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin># Build native executable (requires GraalVM or Docker)
mvn -Pnative native:compile
# Build native Docker image (no GraalVM installation needed)
mvn -Pnative spring-boot:build-imageReal-world results (Spring team numbers):
| JVM | Native | |
|---|---|---|
| Startup time | ~2-5s | ~50-200ms |
| Memory (RSS) | ~300MB | ~50-80MB |
| Throughput | High (JIT) | ~10-20% lower |
| Build time | ~30s | 3-10 minutes |
Mechanism — AOT (Ahead-of-Time compilation):
- Spring Boot 3 analyses the app at build time and generates reflection metadata.
- The Native Image tool compiles everything into a binary.
- Closed-world assumption: all code must be known at compile time.
Limitations to know:
- Reflection must be declared — Spring handles most of it, but third-party libs may need reflect-config.json.
- Dynamic proxies are limited — Spring AOP via CGLIB can encounter issues.
- Classpath scanning does not work at runtime.
- Slow builds — CI pipelines need to account for the time.
When to use Native Image:
- Serverless / AWS Lambda — cold start matters.
- CLI tools built with Spring Shell.
- Microservices requiring fast startup and low memory.
When NOT to use:
- Apps needing maximum throughput (native is ~10-20% slower than JIT after warmup).
- Heavy use of libraries without GraalVM support.
- Teams without experience debugging native images.