目录
JVM 设计者们的初衷仅仅是单纯地为了满足 Java 程序实现跨平台性,因此避免采用静态编译的方式直接生成本地机器指令,从而诞生了实现编译器在运行时采用逐行解释字节码执行程序的想法
解释器真正意义上所承担的角色就是一个运行时 “翻译者”,将字节码文件中的内容 “翻译” 为对应平台的本地机器指令执行
当一条字节码指令被解释执行完成后,接着再根据 PC 寄存器中记录的下一条需要被执行的字节码指令执行解释操作
在 Java 的发展历史里,一共有两套解释执行器,即古老的字节码解释器、现在普遍使用的模板解释器
由于解释器在设计和实现上非常简单,因此除了 Java 语言之外,还有许多高级语言同样也是基于解释器执行的,比如 Python、Perl、Ruby 等。但是在今天,基于解释器执行已经沦为低效的代名词
为了解决这个问题,JVM 平台支持一种叫做即时编译技术。即时编译的目的是避免函数被解释执行,而是将整个函数体编译为机器码,每次函数执行时,只执行编译后的机器码即可,这种方式可以使执行效率大幅度提升
HotSpot VM 是目前市面上高性能虚拟机代表之一,它采用解释器与即时编译器并存的架构
既然 HotSpot VM 中已经内置 JIT 编译器了,为什么还有使用解释器来 “拖累” 程序的执行性能呢
是因为当程序启动后,解释器可以马上发挥作用,省去编译的时间,立即执行。编译器要想发挥作用,把代码编译成本地代码,需要一定的执行时间,但编译为本地代码后,执行效率高
所以,尽管 JRockit VM(不包含解释器)中程序的执行性能会非常高效,但程序在启动时必然需要花费更长的时间来进行编译。对于服务端应用来说,启动时间并非是关注重点,但对于那些看中启动时间的应用场景而言,或许就需要采用解释器与即时编译器并存的架构来换取一个平衡点。在此模式下,当 Java 虛拟器启动时,解释器可以首先发挥作用,而不必等待即时编译器全部编译完成后再执行,这样可以省去许多不必要的编译时间。随着时间的推移,编译器发挥作用,根据热点探测功能,将有价值的字节码编译为本地机器指令,以获得更高的执行效率
同时,解释执行在编译器进行激进优化不成立的时候,作为编译器的 “逃生门”