HotSpot VM JIT的编译产出,理论上能否被复用?

软件工程师、主攻高级编程语言虚拟机的设计与实现

48 👍 / 6 💬

问题描述

使用 JVM 的大规模的分布式计算中(如 Hadoop MapReduce),对于同质化(代码相同,外部条件、输入数据相似)的代码,仍然需要在不同进程、不同节点上独自进行 JIT 编译。
对编译产出的复用,在理论上是否可行?

题主原本的问题:

HotSpot VM JIT的编译产出,理论上能否被复用?
使用 JVM 的大规模的分布式计算中(如 Hadoop MapReduce),对于同质化(代码相同,外部条件、输入数据相似)的代码,仍然需要在不同进程、不同节点上独自进行 JIT 编译。
对编译产出的复用,在理论上是否可行?

问题说“理论上是否可行”,答案是肯定的。但要追问现在的HotSpot VM是否已经有这样的功能,那么可惜的是,到Oracle JDK 8 / OpenJDK 8为止,还没有。

题主所想像的功能有两种可能的实现方式:

题主提问的角度是从dynamic AOT的方向出发的。现实中确实也有产品级JVM已经提供这样的功能了——例如IBM J9 VM。J9从IBM JDK6开始就伴随Class Data Sharing功能提供jitdata caching,做法正是题主所想像的dynamic AOT。请参考

Enhance performance with class sharing

但——这里千万要注意了:J9的dynamic AOT模式下JIT编译出来的代码,跟正常模式下JIT编译出来的代码是不一样的,前者比后者慢。引用上面链接的IBM文档所说:

AOT code is native code and generally executes faster than interpreted code (although it is not likely to run as fast as JIT-generated code).

普通AOT方面其实Java世界已经有很多实现了。Excelsior JET、GCJ之类都是经验丰富的老兵了。

而最新加入战团的是Oracle JDK 9——Oracle计划在JDK9的某个更新版发布带有静态AOT功能的编译器,这个编译器基于Graal。请参考

Java Goes AOT - JVMLS 2015

。就它目前的实现看,它AOT编译出来的代码还是比HotSpot正常JIT编译出来的代码要慢。

IBM J9的dynamic AOT生成的代码,与Oracle JDK 9的更新版将要发布的AOT生成的代码,默认都是可以进一步触发JIT编译的,这样就结合了AOT代码快速启动与JIT代码速度快两者的优势,强强联手。

Oracle JDK 9的更新版的那个AOT也可以配置为不进一步触发JIT编译。这种模式可以用于目标环境不允许JIT编译的情况,例如iOS上。但这样会降低程序的最高性能。

上面说的信息我已经在知乎回答过很多次,请参考汇总传送门:

Java中有类似于NGen的工具(AOT编译器)吗? - RednaxelaFX 的回答

=========================================

为啥在JVM上AOT编译普遍比JIT编译生成的代码质量还要差呢?这是因为现代主流高性能JVM的JIT编译器都会做非常激进的乐观优化(aggressive speculative optimization),这会利用上各种运行时能获取的信息,例如:

一般的Java代码风格下,每个方法普遍偏小,要想尽量优化就得尽可能的(并且合理的)做方法内联。这是JIT比AOT要容易做得多的地方,而前者比后者代码快的主要源头也就来自于此。

要做AOT编译,无论是普通AOT还是dynamic AOT,都不能在编译后的代码里这么随意的嵌入地址。本质上来说要生成position-independent code(PIC)。

我不太确定IBM J9的dynamic AOT具体生成的代码是哪种情况,但无论如何它为了避免频繁的加载失败都肯定会降低其(相对于正常JIT模式)的优化程度。

其实Sun在JDK6的开发过程中,也有同事尝试过做一个基于HotSpot C1的dynamic AOT的原型,结果发现那个原型在缩短Java应用的启动时间上相比多层编译(tiered compilation)并没有显著提升,于是那个原型就被放弃了。

=========================================

其实要改善Java应用的启动性能,除了AOT编译之外还有很多别的事情可以做。Azul Systems的Zing JVM所提供的ReadyNow!功能就是我们在这方面上的尝试。有兴趣的同学可以关注一下:

Zing

ReadyNow!的简介在此:

Zing® ReadyNow! : ™ : A ‘No Stalls’ Java that starts up fast and stays fast