当前位置: 首页 > 知识库问答 >
问题:

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

翟修永
2023-03-14

我无法理解口译员和JIT之间的区别。例如,从这个答案中:

JVMJava虚拟机-运行/解释/翻译字节码到本机代码

JIT是实时编译器——在运行时将给定的字节码指令序列编译为机器代码,然后在本地执行。它的主要目的是对性能进行重大优化。

两者都产生本机机器代码。然后,从另一个答案来看:

解释器为每条指令动态生成和执行机器代码指令,而不管之前是否执行过。JIT缓存以前已解释为机器代码的指令,并重用这些本机机器代码指令。

在我看来,解释器类似于JIT,因为它还将字节码转换为本机代码,不同之处在于JIT执行一些优化,比如缓存。

这对吗?还有其他主要区别吗?

共有2个答案

仲君昊
2023-03-14

本声明:

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

是假的。

简单地说,解释器是一个程序,它循环一个程序的指令(无论是来自虚拟指令集还是真实指令集),并逐一执行这些指令。这是通过编程输出每个指令应该做什么,并在解释器中模拟来完成的。

在最简单的层面上,您可以想象一个解释器通常是这样的:

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

这与CPU执行机器代码的方式没有太大区别,但在CPU的情况下,大多数逻辑直接在硬件中实现。

我想你可以说解释器是在软件中模拟CPU的程序。

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

对于JVM,这是在方法“热”时完成的,即当它大量运行时。然而,JIT编译需要很长的时间(尝试运行带有标记的Java程序,默认情况下强制C2编译,您将看到启动时间的差异),因此首先解释字节码会更快。这还提供了收集分析数据的机会,这些数据是关于程序如何运行的数据(例如,if分支被触发了多少次,或者用于动态调度调用的类型)。在JIT编译过程中也会使用分析数据来进行更好的优化。

许曦
2023-03-14

我认为上述定义不一定正确。

解释器翻译成机器代码不是“强制性的”或“必要的”。

本质上,解释器进行解释。它找到一个循环,然后“运行”该循环。这与创建执行循环的机器代码不同。

 类似资料:
  • 我正在潜入angular 4,我试图理解编译。我已经读到,AOT和JIT都将TypeScript编译为JavaScript,无论是在服务器端还是在客户端。如果我在用Webpack和grunt构建它时编译它,并部署简化的javascript,那么AOT和JIT又是如何出现的呢?

  • 问题内容: Sun的规范JVM实现对字节码进行了一些相当复杂的优化,以在代码运行几次后获得接近本机的执行速度。 问题是,为什么没有将此编译后的代码缓存到磁盘以供以后使用同一功能/类时使用? 就目前而言,每次执行程序时,JIT编译器都会重新启动,而不是使用代码的预编译版本。当本质上解释字节码时,是否添加此功能不会大大提高程序的初始运行时间? 问题答案: 我不求助于@MYYN发布的链接的’n’past

  • 在持久性方面,spark中的和有什么区别?

  • 据我所知,JIT将字节码编译成运行速度更快的本机代码。因此,根据我的信念,我的问题的答案应该是1。翻译成机器代码2。解释字节码。因为解释代码意味着执行代码。但我发现答案恰恰相反!谁能解释一下。。。提前感谢

  • 我用Xtext写了一个DSL。我想要的是执行DSL,从中获得一些好的结果。 我编写了myDslGenerator类,在xtend中实现接口IGenerator,以生成java代码,它运行良好。 我有两个问题; 解释器和代码生成器有什么区别?不都是为了执行DSL吗? 如何编写一个解释器?有没有一步一步的教程链接?我找到了许多使用xint生成代码的教程,但找不到任何用于编写解释器的教程。 谢谢你, 萨

  • 问题内容: 我已经仔细阅读了有关该主题的 AngularJS 文档,然后摆弄了一条指令。这是jsfiddle。 以下是一些相关的摘要: 从 HTML : 从窗格指令: 我没有几件事: 为什么必须与和一起使用? 我是否还可以直接访问父范围,而不用属性装饰元素? 该文档说: “通常希望通过表达式将数据从隔离的范围传递到父范围” ,但这似乎也可以与双向绑定一起使用。为什么表达途径会更好? 我发现了另一个