OpenJDK HotSpot 或将在 Java 9 带来预先编译技术(AOT)

  • Monica Beckwith
  • 薛命灯

2016 年 10 月 10 日

话题:JavaDevOps语言 & 开发

在“什么是即时编译(JIT)!?OpenJDK HotSpot VM 剖析”这篇文章里,作者提到 HotSpot 执行引擎有一个即时(JIT)编译器。为了优化启动时间,分层编译先对代码进行解释,然后把它们快速移动到第 1 层,第 2 层和第 3 层,在这些层里使用客户端编译级别对它们进行编译(使用不同的剖析信息),最后把它们移动到服务端编译级别的层(更多信息可以参考上面的文章)。尽管有编译阶段的优化,HotSpot 仍然会先解释执行字节码,然后才会使用即时编译。

今年 9 月,一个关于在 HotSpot 里添加预先编译(Ahead-of-Time,AOT)的提案被提交到 JEP。AOT 通过加载预编译的类来优化启动时间,避免了在解释模式或局部优化编译级别运行这些类。

AOT 并非新出现的动态编译器技术。IBM 的 J9 虚拟机就支持 AOTExcelsior JET和其它一些虚拟机也支持。AOT 使用(共享)已经编译成本地代码的库让动态编译器达到更好的启动 / 预热效果。

跟 JIT 编译器类似,AOT 编译也有分层和非分层两种模式,不同之处在于剖析信息和 JIT 再编译。那篇文章提到,在分层模式下,编译第 2 层会收集简单的剖析信息,AOT 分层编译的代码也是如此。当 AOT 调用达到一定阈值,这些方法会在第 3 层被客户端编译器编译,这也为将在第 4 层发生的服务端再编译收集了全部剖析信息。

该提案由 HotSpot 团队负责人 Valdimir Kozlov 提交,里面提到了在第一个版本里只有 java.base 模块支持多层 AOT,因为这个基本模块为众人所知,可以得到全面的内部测试。

AOT 带来了一个叫作“jaotc”的工具,它在内部使用了Graal(用于生成代码)。Graal 动态编译器集成了 HotSpot 虚拟机并且依赖JVM 编译器接口(JVMCI),所以 JDK(支持 Graal 或 AOT)应该也支持 JVMCI。Oracle technetwork 网站上就有一些支持 JVMCI 的 JDK 版本。

根据提案的描述,jaotc 工具支持以下这些标记:

--module  Module to compile
--output  Output file name
--compile-commands  Name of file with compile commands
--compile-for-tiered Generated profiling code for tiered compilation
--classpath  Specify where to find user class files
--threads  Number of compilation threads to be used
--ignore-errors Ignores all exceptions thrown during class loading
--exit-on-error Exit on compilation errors
--info Print information during compilation
--verbose Print verbose information
--debug Print debug information
--help Print this usage message
--version Version information
-J Pass  directly to the runtime system

产品级的 JVM 有如下标记:

+/-UseAOT            - Use AOT-compiled files
+/-PrintAOT          - Print used AOT klasses and methods
AOTLibrary=    - Specify the AOT library file

一些非产品级或用于开发的标记对用户也是可用的:

PrintAOTStatistics   - Print AOT statistics
UseAOTStrictLoading  - Exit the VM if any of the AOT libraries has invalid config

提案同时提到,AOT 的运行时事件日志将集成统一 GC 日志,并支持如下标签:

aotclassfingerprint
aotclassload
aotclassresolve

不列出风险或没有基本假定的提案是不完整的,AOT 也不例外。AOT 提案的风险标注如下:

预编译的代码可能不是最优的,所以会导致性能损失。性能测试结果表明,有些应用程序会从 AOT 编译的代码中获益,不过有些却出现明显的性能衰退。因为 AOT 特性是可选的,所以应用程序出现的性能衰退是可以避免的。如果用户发现应用程序启动变慢,或者达不到预期的性能峰值,那么可以重新构建一个不包含 AOT 库的 JDK。

查看英文原文:Ahead-of-Time (AOT) Compilation May Come to OpenJDK HotSpot in Java 9


感谢夏雪对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

JavaDevOps语言 & 开发