代码之家  ›  专栏  ›  技术社区  ›  Michiel Borkent

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

  •  453
  • Michiel Borkent  · 技术社区  · 16 年前

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

    18 回复  |  直到 16 年前
        1
  •  457
  •   Mark Cidade    13 年前

    运行JIT编译器 之后 该程序已经启动,并将代码(通常是字节码或某些类型的虚拟机指令)实时(或者按照它的调用及时)编译成通常更快的形式,通常是主机CPU的本机指令集。JIT可以访问动态运行时信息,而标准编译器则不能,而且可以进行更好的优化,如经常使用的内联函数。

    这与传统的编译器不同 全部的 机器语言代码 之前 程序是第一次运行。

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

        2
  •  234
  •   Craig Trader    16 年前

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

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

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

        3
  •  63
  •   Brian Tompsett - 汤莱恩 andrewwong97    8 年前

    准时生产 当需要时(按需),这个词本身就会说出来。

    典型场景:

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

    JIT情景:

    源代码将被转换成类似于汇编语言的结构[对于C语言的EXIL(中间语言),用于Java的字节码]。

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

    JIT与非JIT比较:

    • 在JIT中,并非所有代码都首先转换为机器代码A部分 所需的代码将转换为机器代码 如果调用的方法或功能不在计算机中,那么 将转换为机器代码…它减少了CPU的负担。

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

    JIT实例:

    1. 在JAVA中,JIT位于JVM(Java虚拟机)中
    2. 在C中,它位于clr(公共语言运行库)中。
    3. 在安卓系统中,它位于dvm(dalvik虚拟机)或art(安卓运行时)的较新版本中。
        4
  •  25
  •   Aniket Thakur    11 年前

    正如其他人提到的

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

    只需在上面的讨论中添加一点,jvm就可以维护一个函数执行时间的计数。如果该计数超过预定义的限制,JIT将代码编译成可直接由处理器执行的机器语言(与JavaC将代码编译成字节码和Java的正常情况不同,解释器逐行解释该字节码将其转换成机器代码并执行)。

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

        5
  •  11
  •   user8885515    7 年前

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

    enter image description here

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

    enter image description here

    Source

        6
  •  9
  •   Brian Lyttle    16 年前

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

    这是有益的,因为编译器可以生成为您的特定机器优化的代码。静态编译器和一般的C编译器一样,将把上的所有代码编译成开发人员计算机上的可执行代码。因此,编译器将根据一些假设执行优化。它可以更慢地编译,并做更多的优化,因为它不会减慢用户程序的执行。

        7
  •  9
  •   xlm santhosh reddy    8 年前

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

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

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

        8
  •  7
  •   xlm santhosh reddy    8 年前

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

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

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

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

    不需要反复编译字节码10次,因为相同的指令将执行10次。在这种情况下,只需编译该代码一次,就可以根据需要的次数更改该值。因此,实时(JIT)编译器跟踪这些语句和方法(如上所述),并将这些字节代码编译成机器代码以获得更好的性能。

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

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

    看到这个 Oracle documentation on Understand JIT 多读书。

        9
  •  4
  •   Charles Graham    16 年前

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

        10
  •  4
  •   eze    11 年前

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

        11
  •  2
  •   user3459027    11 年前

    jit代表实时编译器 JIT是一个程序,它将Java字节码转换成可以直接发送给处理器的指令。

    在特定的系统平台上使用Java即时编译器(真的是第二编译器)将字节码转换成特定的系统代码,一旦代码由JIT编译器重新编译,它通常在计算机中运行得更快。

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

        12
  •  2
  •   Willem van der Veen    6 年前

    实时编译器(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通常会感觉到,并且会编译这一部分以加快执行速度。
        13
  •  1
  •   David    16 年前

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

        14
  •  1
  •   Girdhar Singh Rathore    9 年前

    下面的代码示例演示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的字段值。

        15
  •  1
  •   prime    7 年前

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

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

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

    例如,Hotspot JVM JIT编译器生成动态优化。换言之, 当Java应用程序运行并生成高性能的本机指令时,它们进行优化决策。 针对底层系统架构。

    当选择一个方法进行编译时,JVM将其字节码提供给实时编译器(JIT)。JIT需要先了解字节码的语义和语法,然后才能正确编译该方法。为了帮助JIT编译器分析该方法,首先在称为跟踪树的内部表示中重新编写其字节码,这与机器代码比字节码更为相似。然后对该方法的树进行分析和优化。最后,这些树被转换成本地代码。

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

    参考:

        16
  •  0
  •   Santosh budhe    11 年前

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

        17
  •  0
  •   Venkata Santhosh Piduri    10 年前

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

        18
  •  0
  •   hi.nitish    8 年前

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