执行引擎

我们知道虚拟机和物理机都是一种执行机构,其区别是物理机建立在具体硬件和操作系统之上,而虚拟机是软件实现的,因此能够不受物理条件限制的定制指令集和执行引擎的结构体系,达到Java所说的“一次编写到处运行”的目的。

执行引擎是Java虚拟机的核心组成部分之一,负责将JVM字节码指令解释执行或JIT编译为对应平台上的机器码执行。实际上现在版本的HotSpot中既包含解释器也包含JIT编译器,解释执行和热点代码即时编译执行同时存在,这也是我们常说的“Java是半编译半解释型语言”的出处。

解释器和JIT编译器

HotSpot架构中既包含解释器也包含JIT编译器。

解释器很好理解,它承担一个运行时的“翻译者”,将字节码文件中的内容“翻译”为对应平台的本地机器指令执行,当一条字节码指令被解释执行完成后,再根据PC程序计数器中记录的下一条需要被执行的字节码指令执行解释操作。解释器虽然设计和实现相对简单,但运行效率也比较低。

JIT(Just In Time)即时编译能够实现在运行时将字节码编译为本地机器码执行,相比解释器这样能大大提高运行效率。虽然JIT编译后运行比解释器会快很多,但JIT编译本身需要消耗一定的时间,这相对解释器来说是一个劣势。

不过实际上,HotSpot能够自动检测热点代码(方法体或循环体),一段代码起初会以解释器的方式执行,当这部分代码被反复执行时就会对其进行即时编译,这样就兼顾了解释器和JIT编译器的优点,各自取长补短,实现了更好的性能表现。

我们在控制台中输入java -version时,可以看到类似如下的提示信息:

openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

其中mixed mode就是解释器和JIT混合执行模式,当然我们也可以手动调整仅解释器或是仅JIT,但大多数情况下这样做没有太大意义,这里就不多介绍了。

AOT编译器

AOT(Ahead Of Time Compiler)即提前编译器,相对于JIT即时编译,AOT能够将我们的Java代码直接在编译阶段全部编译成本地机器码,这样执行时就没有什么解释器、JIT编译器的参与了,机器码会直接在物理机上执行相关的逻辑。Graal编译器能够实现AOT编译,这部分内容可以参考GraalVM相关章节。

AOT的优点就是编译阶段已经编译成了本地机器码,没有即时编译器预热造成“启动慢”、“第一次运行慢”等各种问题;不过其缺点是破坏了“一次编写到处运行”的宗旨,AOT编译需要针对各种硬件和操作系统平台发布不同的发行包。此外AOT编译对代码实现也有限制,AOT降低了Java链接过程的动态性,加载的代码在编译期就必须全部已知。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap