与非 JIT 编译器相比,JIT 编译器具体做了什么?有人可以给出一个简洁易懂的描述吗?

有帮助吗?

解决方案

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

这与编译的传统编译器形成对比 全部 机器语言代码 程序首次运行。

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

其他提示

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

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

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

jit joust及时地说,单词本身在需要时说(按需)

典型场景:

源代码完全转换为机器代码

JIT场景:

源代码将被转换为类似于汇编语言的结构[对于 C# 来说是 IL(中间语言),对于 java 来说是 ByteCode]。

仅当应用需要时才将中间代码转换为机器语言,即仅将所需代码转换为机器代码。

JIT 与非 JIT 比较:

  • 在JIT中,并非所有代码首先将所有代码转换为机器代码,而所需的代码的一部分将转换为机器代码,则如果未在机器中使用的方法或功能,则将将其转换为机器代码...它减轻了CPU的负担。

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

JIT 示例:

  1. Java 中的 JIT 位于 JVM(Java 虚拟机)中
  2. 在 C# 中,它位于 CLR(公共语言运行时)中
  3. 在 Android 中,它位于 DVM(Dalvik 虚拟机)中,或者在较新版本中位于 ART(Android 运行时)中。

正如其他人提到的

JIT 代表即时,这意味着代码在需要时进行编译,而不是在运行时之前。

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

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

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

enter image description here

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

enter image description here

来源

JIT 代表即时,这意味着代码在需要时进行编译,而不是在运行时之前。

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

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

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

JIT 编译器仅在运行时工作,因此我们没有任何二进制输出。

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

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

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

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

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

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

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

看到这个 有关理解 JIT 的 Oracle 文档 阅读更多内容。

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

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

JIT代表及时编译器JIT是一个程序,它将Java Byte代码变成可以直接发送给处理器的指令。

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

即时编译器是虚拟机自带的,可以选择使用。它将字节码编译成立即执行的特定于平台的可执行代码。

即时编译器 (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 首先处理中间数据(例如Java 字节码)通过解释将其接收为机器语言。JIT 通常可以感知代码的某个部分何时经常执行,并且会编译该部分以加快执行速度。

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

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

IT编译是一个 的组合 翻译为机器代码的两种传统方法 - 提前编译 (AOT), , 和 解释 – 并结合了两者的一些优点和缺点。 JIT 编译将编译代码的速度与解释的灵活性结合起来.

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

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

当选择一种方法进行编译时,JVM 会将其字节码提供给即时编译器 (JIT)。JIT 需要理解字节码的语义和语法,然后才能正确编译方法。为了帮助 JIT 编译器分析该方法,首先将其字节码重新表述为称为跟踪树的内部表示形式,该表示形式比字节码更类似于机器代码。然后对该方法的树进行分析和优化。最后,树被翻译为本机代码。

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

参考 :

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top