根据JEP 295
任何JDK模块,类或用户代码的AOT编译都是实验性的,在JDK 9中不受支持。
要使用AOTed java.base模块,用户必须编译模块并将生成的AOT库复制到JDK安装目录中,或在java命令行中指定它。
我对上述语句感到困惑,如果JDK 9不支持AOT那么我们如何使用AOT编译模块?
我的第二个问题是,如果JDK 9中有很多advantages over JIT?
,则不支持AOT答案 0 :(得分:3)
首先从你的问题回答后一部分。在与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中进行了实验。
这些限制可以在将来的版本中解决,那时我非常确定将删除该功能中的实验标记。
如果JDK 9不支持AOT,那么我们如何使用AOT编译模块?
为了使用AOT,需要使用jaotc
编译器编译应用程序代码,考虑到上面列出的一些限制。如Ahead-of-Time Compilation: AOT Usage中所述,如果AOT库已使用该工具编译为:
jaotc --output libHelloWorld.so HelloWorld.class
它可以在执行阶段使用
java -XX:AOTLibrary=./libHelloWorld.so HelloWorld
提供了相同版本的JVM配置,在编译时和运行时都使用。
使用上述命令触发执行后,通过默认开启使用AOT编译文件。要切换是否使用这些文件,引入了可在执行阶段使用的新参数。即 -
-XX:+/-UseAOT
更重要的是,与上述两个问题相关,甚至在提案的风险和假设部分中明确提到:
如果用户发现应用程序启动速度较慢,或者未达到预期的峰值性能或崩溃,则只能切换 使用
-XX:-UseAOT
标志关闭AOT,或删除任何AOT库。