实时(JIT)编译器做什么?

时间:2008-09-18 18:52:09

标签: compilation compiler-construction jit

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

20 个答案:

答案 0 :(得分:467)

JIT编译器在程序启动后运行并将代码(通常是字节码或某种VM指令)动态编译(或者即时,如其所称)编译成一个通常更快的表单,通常是主机CPU的本机指令集。 JIT可以访问动态运行时信息,而标准编译器则无法进行更好的优化,例如内联频繁使用的函数。

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

为了解释,传统编译器在第一次运行之前将整个程序构建为EXE文件。对于较新的样式程序,使用伪代码(p代码)生成程序集。只有在OS上执行程序后(例如,通过双击其图标),(JIT)编译器才会启动并生成基于Intel处理器或其他任何人都能理解的机器代码(m代码)。 p>

答案 1 :(得分:240)

最初,编译器负责将高级语言(定义为高于汇编程序的语言)转换为目标代码(机器指令),然后将其(通过链接器)链接到可执行文件中。

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

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

答案 2 :(得分:63)

JIT-及时 这个词本身就说需要(按要求)

典型情况:

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

JIT场景:

源代码将转换为汇编语言,如结构[对于C#的ex IL(中间语言),对于java的ByteCode]。

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

JIT与非JIT比较:

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

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

JIT示例:

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

答案 3 :(得分:25)

正如其他人提到的那样

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

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

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

答案 4 :(得分:11)

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

enter image description here

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

enter image description here

Source

答案 5 :(得分:9)

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

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

答案 6 :(得分:9)

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

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

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

答案 7 :(得分:7)

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

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

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

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

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

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

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

请参阅此Oracle documentation on Understand JIT了解详情。

答案 8 :(得分:4)

你有一些代码被压缩成一些IL(中间语言)。运行程序时,计算机无法理解此代码。它只能理解本机代码。因此,JIT编译器可以动态地将您的IL编译为本机代码。它在方法级别执行此操作。

答案 9 :(得分:4)

我知道这是一个旧线程,但运行时优化是JIT编译的另一个重要部分,似乎没有在这里讨论过。基本上,JIT编译器可以在程序运行时监视程序,以确定改进执行的方法。然后,它可以在运行期间动态地进行这些更改。 Google JIT优化(javaworld有一个漂亮的good article about it.

答案 10 :(得分:2)

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

在特定系统平台上使用java及时编译器(实际上是第二个编译器)将字节码符合特定的系统代码,一旦代码被jit编译器重新编译,它通常会在电脑。

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

答案 11 :(得分:2)

即时编译器(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经常可以感觉到何时经常执行代码的特定部分,并且它将编译该部分以加快执行速度。

答案 12 :(得分:1)

以下代码示例显示了JIT如何优化Java代码。

优化前的代码

    class A {
      B b;
      public void newMethod() {
        y = b.get();
        ...do stuff...
        z = b.get();
        sum = y + z;
      }
    }

class B {
   int value;
   final int get() {
      return value;
   }
}

优化后的代码

class A {
B b;
public void newMethod() {
   y = b.value;
   ...do stuff...
   sum = y + y;
}
}
class B {
   int value;
   final int get() {
      return value;
   }
}

最初,代码包含对b.get()方法的两次调用。优化后,两个方法调用被优化为单个变量复制操作;也就是说,优化代码不需要执行方法调用来获取B类的字段值。

答案 13 :(得分:1)

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

答案 14 :(得分:1)

实时(JIT)编译(也是动态转换或运行时编译)是执行计算机代码的方式 涉及执行期间的编译一个程序 - 在运行时 - 而不是在执行之前

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

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

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

当选择一种方法进行编译时,JVM将其字节码提供给即时编译器(JIT)。在正确编译方法之前,JIT需要理解字节码的语义和语法。为了帮助JIT编译器分析该方法,它的字节码首先在一个称为跟踪树的内部表示中重新构造,它比机器代码更接近于字节码。然后对该方法的树执行分析和优化。最后,树被翻译成本机代码。

  

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

参考:

答案 15 :(得分:0)

使用JIT编译器,Java源代码被转换为Java字节代码(.class文件)。 完成此操作后,JVM将在运行时加载.class文件,并使用解释器将它们转换为机器可理解的代码。

JIT编译器是JVM的一项功能,启用该功能可使JVM分析字节码中的方法调用,并将其编译为更本地有效的代码。此时,JIT会优化优先方法调用。

一旦这些方法调用被编译,JVM将执行优化的代码,而不是解释它,这可能会提高执行性能。

而不是普通的编译器,后者每次执行程序时都必须编译源代码

答案 16 :(得分:0)

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

答案 17 :(得分:0)

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

答案 18 :(得分:0)

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

答案 19 :(得分:0)

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