按照JEP 295
AOT compilation of any JDK modules,classes,or of user code,is experimental and not supported in JDK 9.
To use the AOTed java.base module,the user will have to compile the module and copy the resulting AOT library into the JDK installation directory or specify it on java command line.
我对上面的语句感到困惑,如果JDK 9不支持AOT那么我们如何使用AOT编译模块?
我的第二个问题是为什么AOT在JDK 9中不受支持,如果它有很多advantages over JIT?
首先从你的问题回答后一部分.在与Java 9 API的兼容性方面,AOT并未完全成熟.它在链接的JEP中列出的一些限制是:
>它仍然局限于基于64位Linux的系统.
>要使用AOT编译,用户需要使用相同的JDK进行编译和执行.有关用于编译的jaotc的版本信息作为库的一部分添加,并在加载时检查.如果更新了Java运行时,则需要在执行之前重新编译AOT编译的模块.用于编译和执行的JDK版本不匹配可能导致应用程序崩溃.
> AOT编译器目前不支持Lambda表达式和Java的其他复杂概念,它们在运行时使用动态生成的类.
>要生成共享对象(.so)文件,系统需要预先安装libelf.
> java.base的逻辑编译模式是分层AOT,因为希望JIT重新编译java.base方法以达到最佳性能.只有在某些情况下,非分层AOT编译才有意义.这包括需要可预测行为的应用程序,当占用空间比峰值性能更重要时,或者对于不允许动态代码生成的系统.在这些情况下,需要在整个应用程序上进行AOT编译,因此在JDK 9中进行了实验.
这些限制可以在将来的版本中解决,那时我非常确定将删除该功能的实验标记.
if AOT is not supported in JDK 9 then how can we compile the module using AOT?
为了利用AOT,应用代码需要使用jaotc编译器进行编译,考虑到上面列出的一些限制.如Ahead-of-Time Compilation: AOT Usage中所述,如果使用该工具编译AOT库,则:
jaotc --output libHelloWorld.so HelloWorld.class
它可以在执行阶段使用
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
提供相同版本的JVM配置在编译时和运行时期间使用.
一旦使用上面的命令触发执行,默认情况下使用AOT编译的文件为ON.要切换是否使用这些文件,引入了可在执行阶段使用的新参数.即 –
-XX:+/-UseAOT
更重要的是,与上述两个问题相关,甚至在提案的风险和假设部分中明确提到:
If a user finds that an application starts up more slowly,or doesn’t reach the expected peak performance,or crash,they can just switch
AOT off with the-XX:-UseAOT
flag,or remove any AOT libraries.