好的,我已经阅读了几个关于JIT和非JIT启用的解释器之间差异的讨论,以及为什么JIT通常会提升性能。
但是,我的问题是:
最终,非JIT启用的解释器是否必须将字节码(逐行)转换为要执行的机器/本机代码,就像JIT编译器一样?我已经看到过它的帖子和教科书,以及说它没有的帖子。后一个参数是解释器/ JVM直接执行此字节码而不与机器/本机代码交互。
如果非JIT解释器确实将每一行转换为机器代码,那么JIT的主要好处似乎是......
缓存字节码的所有(普通JIT)或经常遇到的(热点/自适应优化)部分的智能,以便每次都不需要机器代码编译步骤。
任何优化JIT编译器都可以将字节码转换为机器代码。
提前致谢。
答案 0 :(得分:9)
非JIT解释器不会将字节码转换为机器码。您可以想象非JIT字节码解释器的工作方式(我将使用类似Java的伪代码):
int[] bytecodes = { ... };
int ip = 0; // instruction pointer
while(true) {
int code = bytecodes[ip];
switch(code) {
case 0;
// do something
ip += 1; break;
case 1:
// do something else
ip += 1; break;
// and so on...
}
}
因此,对于每个执行的字节码,解释器必须检索代码,切换其值以决定要做什么,并在进入下一次迭代之前递增其“指令指针”。
使用JIT,所有开销都将减少到零。它只需要适当的开关分支的内容(表示“//做某事”的部分),在内存中将它们串在一起,然后执行跳转到第一个分支的开头。不需要软件“指令指针” - 只有CPU的硬件指令指针。不从内存中检索字节码并切换它们的值。
编写虚拟机并不困难(如果它不必具有极高的性能),并且可能是一项有趣的练习。我为嵌入式项目做过一次,程序代码必须非常紧凑。
答案 1 :(得分:0)
6502(也许还有8080)的许多常见Microsoft BASIC解释器对存储在RAM中的代码进行了更广泛的使用,但存储在RAM中的代码并不显着依赖于正在执行的程序;大部分RAM例程在程序执行期间不会改变,但是下一条指令的地址作为例程的一部分保持在线,允许使用绝对模式“LDA”指令,这节省了至少一个周期每个字节提取。