AOT 和 JIT
JDK 17 对 Java 编译技术做了调整。
编译方式回顾
JIT(Just-In-Time)编译
bash
# 传统方式:运行时编译
java -jar app.jar
# 启动后,JIT 编译器把热点代码编译成机器码特点:
- 启动慢(需要编译)
- 运行时优化(性能更好)
- 内存占用高(JIT 编译器)
AOT(Ahead-Of-Time)编译
bash
# 提前编译:构建时生成机器码
jaotc --output lib.so --class-name MyApp MyApp.class
# 运行时代替 JIT
java -A:lib=lib.so -jar app.jar特点:
- 启动快(不需要编译)
- 无运行时优化(性能可能不如 JIT)
- 构建时间长
JDK 17 的变化
移除了 jaotc
bash
# JDK 16 及之前
jaotc --output lib.so MyApp.class
# JDK 17
# jaotc 已被移除原因
- GraalVM 的崛起:GraalVM 提供了更好的 AOT 能力
- 维护成本:jaotc 维护负担大
- Native Image:GraalVM Native Image 是更好的选择
GraalVM Native Image
如果你需要 AOT 编译,使用 GraalVM Native Image:
bash
# 安装 GraalVM
gu install native-image
# 构建原生镜像
native-image -jar app.jar myapp
# 运行(像本地程序一样)
./myappNative Image 特点
| 特性 | JVM | Native Image |
|---|---|---|
| 启动时间 | 慢 | 极快 |
| 内存占用 | 高 | 低 |
| 预热 | 需要 | 不需要 |
| 动态特性 | 支持 | 受限 |
限制
- 不支持反射(需要配置)
- 不支持动态类加载
- 构建时间长
JIT 改进
虽然移除了 AOT,但 JIT 在持续改进:
JVM CI(JDK 9+)
新的 JIT 编译器接口:
bash
# 使用 GraalVM JIT
java -XX:+UseGraalJIT -jar app.jar提前编译热点
bash
# JDK 17 改进了分层编译
java -XX:+UseZGC -jar app.jar选择建议
| 场景 | 推荐方案 |
|---|---|
| 传统服务器应用 | JVM JIT |
| 微服务/Kubernetes | GraalVM Native Image |
| Serverless | GraalVM Native Image |
| 大型单体应用 | JVM JIT |
| 短生命周期程序 | GraalVM Native Image |
示例:Spring Boot + Native Image
xml
<!-- pom.xml -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>小结
JDK 17 的编译技术变化:
- 移除了 jaotc:AOT 编译改用 GraalVM
- GraalVM Native Image:更好的 AOT 方案
- JIT 持续改进:分层编译更智能
如果你需要快速启动,考虑 GraalVM Native Image;如果需要最佳运行时性能,使用标准 JVM。
