JIT与AOT

JIT

JIT(Just-in-Time,实时编译)一直是Java语言的灵魂特性之一,HotSpot JVM中集成了两种JIT编译器,Client Compiler和Server Compiler,它们的作用也不同。Client Compiler注重启动速度和局部的优化,Server Compiler则更加关注全局的优化,性能会更好,但由于会进行更多的全局分析,所以启动速度会变慢。两种编译器有着不同的应用场景,在虚拟机中同时发挥作用。而随着时间的发展,不论是Client Compiler还是Server Compiler都发展出了各具特色的实现,如 C1、C2、Graal Compiler等,你可以在JVM启动参数中选择自己所需的JIT编译器实现。

JIT与AOT的区别

提前编译是相对于即时编译的概念,提前编译能带来的最大好处是Java虚拟机加载这些已经预编译成二进制库之后就能够直接调用,而无须再等待即时编译器在运行时将其编译成二进制机器码。理论上,提前编译可以滅少即时编译带来的预热时间,减少Java应用长期给人带来的“第一次运行慢"的不良体验,可以放心地进行很多全程序的分析行为,可以使用时间压力更大的优化措施。但是提前编译的坏处也很明显,它破坏了Java"—次编写,到处运行"的承诺,必须为每个不同的硬件、操作系统去编译对应的发行包;也显著降低了Java链接过程的动态性,必须要求加载的代码在编译期就是全部已知的,而不能在运行期才确定,否则就只能舍弃掉己经提前编译好的版本,退回到原来的即时编译执行状态。

AOT的优点

在程序运行前编译,可以避免在运行时的编译性能消耗和内存消耗
可以在程序运行初期就达到最高性能,程序启动速度快
运行产物只有机器码,打包体积小

AOT的缺点

由于是静态提前编译,不能根据硬件情况或程序运行情况择优选择机器指令序列,理论峰值性能不如JIT
没有动态能力,使用到反射、动态编译需要额外处理。
同一份产物不能跨平台运行。

Native Image:原理与限制

Native Image的输入是整个应用的所有组件,包括应用本身的代码、各种依赖的库、JDK库、以及SVM;首先会进行整个应用的初始化,也就是代码的静态分析,这个分析过程有点类似GC中的“可达性分析”,会讲程序运行过程中将所有可达的代码、变量、对象生成一个快照,最终打包成一个可执行的Native Image。

一个完整的Native Image包含两个部分,一部分称为 Text Section,即用户代码编译成的机器代码;另一部分称为 Data Section,存储了应用启动后堆区内存中各种对象的快照。
例如反射、代理,要如何进行静态分析呢?很显然,这两者之间是存在冲突的,因此Native Image设置了一个名为“Closed World”的假设作为静态分析的基本前提。

这个基本前提包含三个要求,对应的也就是目前Native Image存在的三个限制:

Points-to分析的时候,需要接受完整的字节码作为输入(即项目中所有用到的class的字节码都需要获取的到)。
=> 在运行期动态生成或者是动态获取字节码的程序,无法构建成 Native Image。

Java的动态特性,包括反射、JNI、代理,都需要通过配置文件在构建前实现声明好。
=> 无法提前声明动态特性使用范围的程序,无法构建成Native Image (例如,根据用户输入的一个参数反射去调用某个方法)。

在整个运行过程中,程序不会再加载任何新的class。
=> 在运行期间执行动态编译,或者是自定义Classloader动态装载类的程序,无法构建成Native Image。

Spring Native

Spring框架的Native化支持,包括IOC、AOP等各种Spring组件及能力的Native支持;其次是Configuration支持,允许通过@NativeHint注解来动态生成Native Image Configuration(reflect-config.json, proxy-config.json等);最后就是Maven Plugin,可以通过Maven构建获得Native Image,而不需要再手动去执行native-image命令。

总结

Native Image目前需要面对的最大问题,还是来自于Java世界数以万计的各种库:Netty、fastjson、logback、junit … 尽管很多的开源库都开始改造以支持Native Build。

Java AOT在经过一波三折的发展后,目前最为成熟可行的方案就是 GraalVM Native Image,它所带来的优势是显著的:更快的启动速度、更小的内存消耗、脱离JVM独立运行 。但对应的,它也存在着非常多的限制,尤其是在充满了反射等动态特性的Java工程生态圈,很难得到大规模的广泛应用。

 
posted on 2024-07-04 11:30  zhengbiyu  阅读(46)  评论(0编辑  收藏  举报