除了缓存指令之外,解释器和JIT生成的本机代码之间有什么区别吗?

时间:2018-05-08 10:45:16

标签: java jvm interpreter jit

我无法理解解释器和JIT之间的区别。例如,来自this answer

  

JVM是Java虚拟机 - 运行/解释/翻译字节码   进入原生机器代码

     

JIT是即时编译器 - 编译给定的字节码   执行前在运行时将指令序列强加到机器码   它原生。它的主要目的是进行大量的优化   性能

两者都生成本机机器代码。然后,从this other answer

  

解释器生成并执行机器代码指令   每次指令都会飞,不管以前是否有过   执行。 JIT缓存先前的指令   解释为机器代码,并重用这些本机机器代码   指令。

正如我所看到的,解释器类似于JIT,因为它还将字节码转换为本机代码,区别在于JIT执行一些优化,如缓存。

这是对的吗?还有其他重大区别吗?

2 个答案:

答案 0 :(得分:3)

我认为上述定义并非必然如此。

不是强制性的"或者"必要的" 解释器 转换为机器代码。

本质上,口译员解释。它找到一个循环,然后"运行"那个循环。这与创建执行循环的机器代码相同。

答案 1 :(得分:2)

本声明:

  

解释器生成并执行机器代码指令

是假的。

简单地说,解释器是一个循环程序指令的程序(来自虚拟或实际指令集),并逐个执行。这是通过编写每条指令应该做的事情并在解释器中模拟它来完成的。

在最简单的层面上,你可以想象一个解释器看起来像这样:

for(byte byteCode : program) {
    if(byteCode == ADD_BYTECODE) {
        add();
    }
    // ... others
}

这与CPU执行机器代码的概念没有什么不同,但在CPU的情况下,大多数逻辑都直接在硬件中实现。

我想你可以说解释器是一个用软件模拟CPU的程序。

JIT编译器负责将字节代码转换为机器代码并在此过程中对其进行优化。机器代码优于字节代码的理论优势之一是,例如,特定CPU可能具有比字节代码等效运行得更快的专用指令。

在JVM的情况下,这是在方法是热的时候完成的,即当它运行很多时。 JIT编译需要很长时间(尝试运行带有-XX:-TieredCompilation -Xcomp标志的Java程序,默认情况下强制C2编译,你会看到启动时间的差异),所以它更快首先解释字节码。这也提供了收集分析数据的机会,分析数据是关于程序如何运行的数据(例如,if分支被触发多少次,或者哪些类型用于动态分派调用)。在JIT编译期间也使用分析数据来进行更好的优化。