6

根据JEP 295

任何 JDK 模块、类或用户代码的 AOT 编译都是实验性的,在 JDK 9 中不受支持。

要使用 AOTed java.base 模块,用户必须编译模块并将生成的 AOT 库复制到 JDK 安装目录或在 java 命令行中指定它。

我对上面的陈述感到困惑,如果 JDK 9 不支持 AOT,那么我们如何使用 AOT 编译模块?

我的第二个问题是,如果 AOT比 JIT 有很多优势,为什么 JDK 9 不支持它?

4

1 回答 1

3

它是一个实验功能。

先从你的问题回答后半部分。AOT 在与 Java 9 API 的兼容性方面并不完全成熟。链接的 JEP 中还列出了一些限制:

  • 它仍然仅限于基于 64 位 Linux 的系统。

  • 要使用 AOT 编译,用户需要使用同一个 JDK 进行编译和执行。用于编译的版本信息jaotc作为库的一部分添加,并在加载时进行检查。如果 Java 运行时更新,则需要在执行之前重新编译 AOT 编译的模块。用于编译和执行的 JDK 版本不匹配可能会导致应用程序崩溃。

  • AOT 编译器目前不支持 Lambda 表达式和其他复杂的 Java 概念,它们在运行时使用动态生成的类。

  • 要生成共享对象 (.so) 文件,需要libelf预先安装系统。

  • 的逻辑编译模式java.base是分层 AOT,因为java.base需要对方法进行 JIT 重新编译以达到最佳性能。只有在某些情况下,非分层 AOT 编译才有意义。这包括需要可预测行为的应用程序,当占用空间比峰值性能更重要时,或者对于不允许动态代码生成的系统。在这些情况下,需要在整个应用程序上进行 AOT 编译,因此在 JDK 9 中是实验性的。

这些限制可以在未来的版本中解决,那时我很确定该功能中的 Experimental 标签将被删除。


如果 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 编译文件在默认情况下为 ON。为了切换是否使用这些文件,引入了可在执行阶段使用的新参数。IE -

-XX:+/-UseAOT    

更重要的是要与上述两个问题相关,甚至在提案的风险和假设部分明确提到:

如果用户发现应用程序启动速度较慢,或者没有达到预期的峰值性能,或者崩溃,他们可以使用-XX:-UseAOT标志关闭 AOT,或删除任何 AOT 库。

于 2017-10-05T07:15:13.353 回答