Java 9 将引入预先编译(Ahead-of-Time Compilation)
更新时间: 2016-10-31 02:21
在 Oracle 的 JDK 中,编译器(javac)基本不执行什么优化操作,JVM(HotSpot)承担了绝大部分的优化工作,而其中功劳,主要又是 JIT (Just-in-Time)编译器的。
近日发布的 JEP 295 意在在 Java 9 中引入预先(Ahead-of-Time,简称 AOT)编译。
简而言之,该 JEP 的目标是在启动虚拟机之前将 Java 类(字节码)编译为原生代码(native code)。
说句题外话,Java 新版本的发布总是各种延期。之前我们就曾提到过一次:Java 9要跳票?又是Project Jigsaw!。按照最初的计划,Java 9 应于今年 9 月发布,上次就推迟了半年(2017 年 3 月 23 日)。近期,发布计划再次调整,正式发布日期推迟到明年 7 月 27 日。不过这也算给一些新特性的引入争取到了时间。
其实 AOT 并不是什么新鲜玩意儿,像 .Net 就有 NGen,Android Runtime(ART)也用到了 AOT。Java 界也有 Excelsior JET。不过在我们最常用的 JDK 中引入,这还是头一遭。
回到正题,一起看看 JEP 295。
目前的 HotSpot 采用的是混合编译模式,字节码先解释执行,当方法调用次数达到某个阈值之后,启动 JIT 编译。带来的问题是,有时候要达到较好的性能,虚拟机需要充分预热。有些使用不是那么频繁的方法,可能根本不会被编译,而是多次解释调用。
HotSpot 有望通过 AOT 缩短 Java 应用的启动时间。
最初的版本将仅支持 java.base 模块。因为这个模块的代码都是可以提前知道的,也可以充分做好内部测试。对其他模块或用户代码而言,该特性还是试验性的。
要使用 AOT 编译的 java.base 模块,用户必须编译该模块,并将生成的 AOT 库复制到 JDK 安装目录下,或者在 java 命令行中指定。
为支持 AOT,JDK 中将引入一个新工具,jaotc。
jaotc --output libHelloWorld.so HelloWorld.class
jaotc --output libjava.base.so --module java.base
jaotc 使用 Graal 作为代码生成后端。
在 JVM 启动时,AOT 初始化代码会查找编译的共享库。也可以在命令行中使用 AOTLibrary 标志指定。如果找到共享库,则加载并使用之。如果没有,对刚启动的这个 JVM 实例而言,AOT 特性将被关闭。
java -XX:AOTLibrary=./libHelloWorld.so,./libjava.base.so HelloWorld