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

关于JIT编译器和解释器的说明

巫马修为
2023-03-14

我对JIT编译器和解释器有些怀疑。从其定义开始:

(翻译)来自维基百科:

在计算机科学中,解释器是一种计算机程序,它直接执行(即执行)用编程或脚本语言编写的指令,而无需事先将其批量编译成机器语言。解释器通常使用以下策略之一执行程序:
1)解析源代码并直接执行其行为
2)将源代码翻译成某种有效的中间表示形式,并立即执行该表示形式
3)显式执行由编译器(解释器系统的一部分)生成的存储预编译代码[1]

(JIT编译器)来自Wikipedia:

在计算中,实时编译(JIT),也称为动态转换,是在程序执行期间(运行时)而不是在执行之前完成的编译。[1] 通常,这包括对机器代码的翻译,然后直接执行,但也可以指对另一种格式的翻译。

从StackOverFlow:

即时编译是在执行前将非本机代码(例如字节码)转换为本机代码。

我有4个问题:
1)总是说JIT=运行时,为什么解释器在运行时不工作?当程序运行时,解释器不是在运行时翻译和执行每一行吗?
2)总是说JIT将非本机代码翻译成本机代码,那又怎样?解释器不将代码转换为本机代码吗?如果没有翻译成本机代码,我的进程如何执行指令?所以解释器也需要将代码翻译成本机代码。
3)普通解释器在需要执行每一行时翻译每一行,而使用即时编译器,每一行都在执行前翻译,因此在需要执行该行的那一刻是可行的。不是吗?
4)那么解释器和即时编译器之间真正的区别是什么,两者都在运行时执行程序,都从中间语言翻译成本机代码...

共有3个答案

严稳
2023-03-14

在这里我将直接回答最后一个问题。

有时Java虚拟机被称为Java解释器;然而,鉴于字节码可以执行的各种方式,这个术语可能会产生误导。虽然“Java解释器”是解释字节码的Java虚拟机的合理名称,但虚拟机也使用其他技术(如即时编译)来执行字节码。因此,尽管所有Java解释器都是Java虚拟机,但并非所有Java虚拟机都是Java解释器。

JIT在少数JVM实现中是指执行引擎,一种更快但需要更多内存的实现是即时编译器。在这种方案中,方法的字节码在第一次调用该方法时被编译为本机机器代码。然后缓存该方法的本机机器代码,以便下次调用同一方法时可以重新使用它。

傅朗
2023-03-14

1) 人们总是说JIT=运行时,为什么解释器不能在运行时工作?当程序运行时,解释器不是在运行时翻译并执行每一行吗?

你是对的;解释必然发生在运行时。

2) 人们总是说JIT将非本机代码转换为本机代码,那又怎样?解释器不会将代码转换为本机代码吗?如果指令未转换为本机代码,我的进程如何执行该指令?因此,解释器也需要将代码转换为本机代码。

的确,所有执行最终都是本机代码。解释器中充满了实现非本机解释指令效果的函数。这些函数是本机代码。

3)普通解释器在需要执行每一行时翻译每一行,而使用即时编译器,每一行都在执行前翻译,因此在需要执行该行的那一刻是可行的。不是吗?

4) 那么,解释器和JIT编译器的真正区别是什么呢?它们都是在运行时执行程序,都是从中间语言转换为本机代码。。。

不同之处在于,JIT可以应用于比单个语句或指令更大的代码段。JIT可以用于编译整个函数、类,甚至整个程序。

JIT编译的优点是,作为将一部分已解释代码编译为本机代码的一次性成本的交换,您可以节省解释的执行开销,并且可以利用当您像解释器那样一次只能查看一条非本机代码时无法执行的优化

这就是为什么JIT编译重复执行的代码部分是有意义的。编译的成本只发生一次,而每次使用代码都会获得好处。

邹毅
2023-03-14

解释器不会将源代码翻译为本机机器代码。虽然您的计算机只能执行机器代码,但它执行的机器代码不一定是高级语言的翻译。困惑?让我们看一个简单的玩具示例...

考虑具有两个函数的编程语言PrintForPony,printchatprint函数将一串字符作为其唯一参数并将其打印到标准输出,而chat将正整数作为其唯一参数并将当前线程Hibernate一段时间。PFP的伪BNF:

program        ::= statement_list
statement_list ::= statement | statement NEWLINE statement_list
statement      ::= print STRING | sleep POSITIVE_INTEGER

这里是一个用于PFP的intepreter的超级简单Java实现。程序将源文件作为其唯一参数,并对其进行解释:

import java.io.BufferedReader;
import java.io.FileReader;

public class PFPInterpreter {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(args[0]));
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.startsWith("print ")) {
                System.out.println(line.substring("print ".length()));
            } else if (line.startsWith("sleep ")) {
                Thread.sleep(Long.parseLong(line.substring("sleep ".length())));
            } else {
                throw new IllegalArgumentException("Unknown function: " + line);
            }
        }
    }
}

示例源文件:

print Hello, World!
sleep 1000
print Goodbye, World!

和样本输出:

$ java PFPInterpreter test.pfp 
Hello, World!
Goodbye, World!

PFP在任何时候都不会转换为本机机器代码。执行的本机机器代码是JVM,它与这种玩具语言无关。我们还可以为PFP编写一个编译器,将代码转换为可执行文件(我不打算,因为这个答案已经太长了),但问题的关键是,解释器不会编译为本机机器代码-它读取输入文件,并根据内容执行某些操作。

回答问题:

1) 解释器是为您运行代码的运行时。我不确定你在哪里读到的口译员在运行时不工作的确切内容,但我也不确定这意味着什么。

2)如上所述,不,解释器不会翻译为本机机器代码。JIT编译器可以。您的处理器只执行本机机器代码,但本机机器代码可能是一个读取任意文件并根据内容执行某些操作的程序。从这个意义上说,解释器实际上只是一个典型的程序,它接受文本文件形式的输入。

3) JIT编译相当复杂,我根本不是专家。然而,以Java的HotSpot为例,在JIT编译器被调用之前,代码块必须执行一定的次数(客户端1500次,服务器15000次,IIRC)。这可能是因为实际的编译不是免费的,而且很可能编译的本机代码被缓存起来以供以后执行(这可以解释许多执行的要求)。这使得JIT编译是一项投资(在时间和空间上),在第一次执行时可能不会更快(甚至更慢),但后续执行会更快,因为编译不再必要,并且本机代码更高效。

4) 见上文。

我希望这有帮助!

 类似资料:
  • 问题内容: 我正在学习Java,以下内容对我来说有些混乱。我了解的是: Java编译器 →Java编译器仅将程序转换为文件,这意味着将我们的源代码转换为字节码(这是使Java平台独立的虚拟机(JVM)的操作码的列表)。 Java Interpreter →仅“解释”代码,而 没有 将其转换为本地机器代码。它将一条字节码的每条指令作为一条命令一一执行并执行,而不管同一条指令出现多少次。这就是为什么它

  • 我正在学习Java,下面的事情让我有点困惑。我的理解是: > Java编译器→Java编译器只是将程序转换为文件,这意味着将我们的源代码转换为字节码(它是虚拟机(JVM)的操作代码列表,使Java平台独立)。 Java解释器→只是“解释”代码,而不是将其转换为本机机器代码。它将字节码的每一条指令作为命令逐一执行并执行,而不管同一条指令发生多少次。这就是为什么它很慢,Java引入了JIT概念。 JI

  • 翻译的结果是什么?它会把高级语言变成汇编语言还是机器语言,即二进制代码? 如果是后者,这是否意味着解释语言与介绍集没有关系? 一种语言只能有一个口译员?是因为解释器不做任何优化,所以我们不需要找到更好的解释器吗?

  • 主要内容:JIT编译器语法,JIT编译器的风险和假设JIT 编译器是用 C++ 编写的,用于将 Java 转换为字节码。现在 Java 10 可以选择启用基于 Java 的实验性 JIT 编译器 Graal 来代替标准的 JIT 编译器。Graal 正在使用 Java 9 中引入的 JVMCI,即 JVM 编译器接口。 Graal 在 Java 9 中也可用。使用 Java 10,我们可以启用 Graal 来测试和调试实验性 JVM 编译器。 JI

  • 问题内容: 为什么我们说Java是一种编译和解释语言? (编译和解释)这样做有什么好处? 问题答案: Java在编译时被编译为中间的“字节码”。这与像C之类的语言在编译时被编译为机器语言相反。Java字节代码无法像编译的C代码那样直接在硬件上执行。相反,字节码必须在运行时由JVM(Java虚拟机)解释才能执行。像C这样的语言的主要缺点是,当编译该二进制文件时,该二进制文件将仅在一种特定的体系结构(

  • 那么,让我看看我是否明白了这一点。 > 当我们说编译器和解释器之间的区别时,解释器将高级指令翻译成中间形式,然后执行。[我认为编译器也将高级指令翻译成中间形式,但此刻它生成目标代码而不是执行它,对吗?] 解释器一次读取一条指令或一行的源代码,将该行转换为机器代码并执行它。[解释器本身不会将代码转换为机器代码,它会使用ist自己的预编译函数评估指令(在解析之后)。例如,高级语言中的Add表达式将使用