608

与非 JIT 编译器相比,JIT 编译器具体做什么?谁能给一个简洁易懂的描述?

4

18 回答 18

590

JIT 编译器程序启动后运行并将代码(通常是字节码或某种 VM 指令)即时(或称为即时)编译成通常更快的形式,通常是主机 CPU 的本机指令系统。JIT 可以访问动态运行时信息,而标准编译器则不能,并且可以进行更好的优化,例如经常使用的内联函数。

这与在程序首次运行之前将所有代码编译为机器语言的传统编译器形成对比。

换句话说,传统的编译器在您第一次运行它之前将整个程序构建为一个 EXE 文件。对于较新样式的程序,使用伪代码(p-code)生成程序集。只有在您在操作系统上执行程序之后(例如,通过双击其图标),(JIT)编译器才会启动并生成基于 Intel 的处理器或任何可以理解的机器代码(m-code)。

于 2008-09-18T18:55:52.207 回答
281

一开始,编译器负责将高级语言(定义为比汇编程序更高的级别)转换为目标代码(机器指令),然后将其链接(通过链接器)成为可执行文件。

在语言发展的某个阶段,编译器会将高级语言编译为伪代码,然后(由解释器)解释该伪代码以运行您的程序。这消除了目标代码和可执行文件,并允许这些语言移植到多个操作系统和硬件平台。Pascal(编译成 P-Code)是最早的之一;Java 和 C# 是最近的例子。最终,术语 P-Code 被字节码取代,因为大多数伪操作都是一个字节长。

Just-In-Time (JIT) 编译器是运行时解释器的一个特性,它不是每次调用方法时都解释字节码,而是将字节码编译成运行机器的机器代码指令,然后调用它而是目标代码。理想情况下,运行目标代码的效率将克服每次运行时重新编译程序的低效率。

于 2008-09-18T19:06:10.310 回答
80

JIT-及时这个词本身说什么时候需要(按需)

典型场景:

源代码完全转化为机器码

JIT 场景:

源代码将被转换为类似结构的汇编语言 [for ex IL (intermediate language) for C#, ByteCode for java]。

只有当应用程序需要将所需代码转换为机器代码时,才将中间代码转换为机器语言。

JIT 与非 JIT 比较:

  • 在 JIT 中,并非所有代码都首先转换为机器代码,一部分必要的代码将被转换为机器代码,然后如果调用的方法或功能不在机器中,那么它将被转换为机器代码......它减少了CPU 的负担。

  • 由于机器代码将在运行时生成...... JIT 编译器将生成针对运行机器的 CPU 架构进行优化的机器代码。

JIT 示例:

  1. 在 Java 中 JIT 在 JVM(Java 虚拟机)中
  2. 在 C# 中,它位于 CLR(公共语言运行时)中
  3. 在 Android 中,它位于 DVM(Dalvik 虚拟机)或较新版本的 ART(Android 运行时)中。
于 2013-04-29T08:55:11.847 回答
35

正如其他人提到的

JIT 代表 Just-in-Time,这意味着代码在需要时被编译,而不是在运行时之前。

只是为了在上面的讨论中添加一点,JVM 维护一个函数执行多少次的计数。如果这个计数超过预定义的限制,JIT 将代码编译成可以直接由处理器执行的机器语言(与 javac 将代码编译成字节码然后 java - 解释器逐行解释这个字节码将其转换为机器代码并执行)。

同样,下次计算此函数时,将再次执行相同的编译代码,这与正常解释不同,其中代码再次逐行解释。这使得执行速度更快。

于 2013-12-10T13:20:45.473 回答
25

JIT 编译器仅在第一次执行时将字节码编译为等效的本机代码。在每次连续执行时,JVM 仅使用已编译的本机代码来优化性能。

在此处输入图像描述

如果没有 JIT 编译器,JVM 解释器会逐行翻译字节码,使其看起来好像正在执行本机应用程序。

在此处输入图像描述

来源

于 2018-01-19T04:37:11.647 回答
16

JIT 代表 Just-in-Time,这意味着代码在需要时被编译,而不是在运行时之前。

这是有益的,因为编译器可以生成针对您的特定机器优化的代码。静态编译器,就像您的普通 C 编译器一样,会将所有代码编译为开发人员机器上的可执行代码。因此,编译器将根据一些假设执行优化。它可以更慢地编译并进行更多优化,因为它不会减慢用户程序的执行速度。

于 2008-09-18T19:00:45.770 回答
8

在 Java 编译器生成字节码(与体系结构无关)后,将由 JVM(在 Java 中)处理执行。字节码将由加载器加载到 JVM 中,然后解释每个字节指令。

当我们需要多次调用一个方法时,我们需要多次解释相同的代码,这可能会花费比需要更多的时间。所以我们有 JIT(即时)编译器。当字节被加载到 JVM(它的运行时)时,整个代码将被编译而不是解释,从而节省时间。

JIT 编译器只在运行时工作,所以我们没有任何二进制输出。

于 2012-08-10T08:46:09.190 回答
6

即时编译器(JIT):
它将java字节码编译成特定CPU的机器指令。

例如,如果我们的 java 代码中有一个循环语句:

while(i<10){
    // ...
    a=a+i;
    // ...
 }

如果 i 的值为 0,则上述循环代码运行 10 次。

没有必要一次又一次地编译字节码 10 次,因为同一条指令将执行 10 次。在这种情况下,只需要编译该代码一次,并且可以将值更改为所需的次数。因此,即时 (JIT) 编译器会跟踪此类语句和方法(如前所述),并将此类字节码编译成机器码以获得更好的性能。

另一个类似的例子是在字符串/句子列表中使用“正则表达式”搜索模式。

JIT Compiler 不会将所有代码编译为机器码。它在运行时编译具有相似模式的代码。

请参阅有关了解 JIT 的 Oracle 文档以了解更多信息。

于 2016-02-27T02:25:02.827 回答
5

即时编译器 (JIT) 是一种软件,它接收不可执行的输入并返回要执行的适当机器代码。例如:

Intermediate representation    JIT    Native machine code for the current CPU architecture

     Java bytecode            --->        machine code
     Javascript (run with V8) --->        machine code

这样做的结果是,对于特定的 CPU 架构,必须安装适当的 JIT 编译器。

差异编译器、解释器和 JIT

虽然当我们想要将源代码转换为机器代码时通常会有例外,但我们可以使用:

  1. 编译器:获取源代码并返回可执行文件
  2. 解释器:逐条执行程序。它获取源代码的一个可执行段并将该段转换为机器指令。重复此过程,直到所有源代码都转换为机器指令并执行。
  3. JIT:JIT 的许多不同实现是可能的,但是 JIT 通常是编译器和解释器的组合。JIT 首先通过解释将其接收到的中间数据(例如 Java 字节码)转换为机器语言。JIT 通常可以测量代码的某个部分何时经常执行,并将编译该部分以更快地执行。
于 2018-09-26T17:15:11.690 回答
4

您有编译成某种 IL(中间语言)的代码。当您运行程序时,计算机不理解此代码。它只理解本机代码。因此,JIT 编译器会即时将您的 IL 编译为本机代码。它在方法级别执行此操作。

于 2008-09-18T18:56:06.780 回答
4

我知道这是一个旧线程,但运行时优化是 JIT 编译的另一个重要部分,这里似乎没有讨论。基本上,JIT 编译器可以在程序运行时对其进行监控,以确定改进执行的方法。然后,它可以在运行时即时进行这些更改。谷歌 JIT 优化(javaworld 有一篇关于它的不错的文章。

于 2014-03-21T13:36:55.570 回答
2

Jit 代表即时编译器 jit 是一个程序,可以将 java 字节码转换为可以直接发送到处理器的指令。

在特定系统平台使用java即时编译器(实际上是第二编译器)将字节码编译成特定的系统代码,一旦代码被jit编译器重新编译,它通常会在计算机中运行得更快。

即时编译器随虚拟机一起提供,可供选择使用。它将字节码编译成平台特定的可执行代码,立即执行。

于 2014-04-16T06:41:06.923 回答
2

即时 (JIT) 编译(也称为动态翻译或运行时编译)是一种执行计算机代码的方式,涉及在程序执行期间(在运行时)而不是在执行之前进行编译。

IT 编译是两种传统的机器代码翻译方法的组合——提前编译 (AOT)解释——并结合了两者的一些优点和缺点。JIT 编译结合了编译代码的速度和解释的灵活性

让我们考虑一下 JVM 中使用的 JIT,

例如,HotSpot JVM JIT 编译器生成动态优化。换句话说,它们在 Java 应用程序运行时做出优化决策,并生成针对底层系统架构的高性能本机机器指令。

选择用于编译的方法时,JVM将其字节码馈送到正常编译器(JIT)。JIT 需要理解字节码的语义和语法才能正确编译方法。为了帮助 JIT 编译器分析该方法,首先将其字节码重新表述为称为跟踪树的内部表示,它更类似于机器码而不是字节码。然后对该方法的树进行分析和优化。最后,树被翻译成本地代码。

跟踪树是在编程代码的运行时编译中使用的数据结构。跟踪树用于一种“即时编译器”,它跟踪热点期间执行的代码并对其进行编译。参考这个

参考 :

于 2018-04-06T09:44:52.233 回答
1

非 JIT 编译器获取源代码并在编译时将其转换为机器特定的字节码。JIT 编译器获取在编译时生成的与机器无关的字节码,并在运行时将其转换为机器特定的字节码。Java 使用的 JIT 编译器允许单个二进制文件无需修改即可在多个平台上运行。

于 2008-09-18T19:08:48.247 回答
0

80% 的时间使用了 20% 的字节码。JIT 编译器获取这些统计信息并通过添加内联方法、删除未使用的锁等以及创建特定于该机器的字节码来优化这 20% 的字节码以更快地运行。我引用这篇文章,我发现它很方便。http://java.dzone.com/articles/just-time-compiler-jit-hotspot

于 2014-07-06T10:12:11.003 回答
0

Just In Time 编译器也称为 JIT 编译器,用于提高 Java 的性能。默认情况下启用。它是在执行时更早完成的编译。Java 通过将 JIT 编译器包含在 JVM 中而普及了 JIT 编译器的使用。

于 2020-03-22T09:56:58.333 回答
-1

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

于 2014-11-03T13:08:12.507 回答
-1

出于性能原因,JVM 实际上会在运行时执行编译步骤。这意味着 Java 没有干净的编译执行分离。它首先进行所谓的从 Java 源代码到字节码的静态编译。然后这个字节码被传递给 JVM 执行。但是执行字节码很慢,因此 JVM 测量字节码运行的频率,当它检测到运行非常频繁的代码“热点”时,它会执行从字节码到“热点”代码的机器码的动态编译(热点分析器)。今天,Java 程序如此有效地通过机器代码执行来运行。

于 2015-12-13T05:21:35.177 回答