与非JIT编译器相比,JIT编译器具体做了什么?有人可以给出一个简洁易懂的描述吗?
答案 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-及时 这个词本身就说需要(按要求)
源代码完全转换为机器代码
源代码将转换为汇编语言,如结构[对于C#的ex IL(中间语言),对于java的ByteCode]。
只有在应用程序需要时,中间代码才会转换为机器语言,只需将代码转换为机器代码。
在JIT中,并非所有代码都首先转换为机器代码 必要的代码将转换为机器代码 然后,如果被调用的方法或功能不在机器中那么 将变成机器代码...它减轻了CPU的负担。
因为机器代码将在运行时生成.... JIT 编译器将生成针对运行进行优化的机器代码 机器的CPU架构。
答案 3 :(得分:25)
正如其他人提到的那样
JIT代表Just-in-Time,这意味着代码在需要时编译,而不是在运行时编译。
只是为了向上面的讨论添加一点,JVM维护一个计算执行函数的次数。如果此计数超过预定义的限制,JIT会将代码编译为机器语言,这可以由处理器直接执行(与javac将代码编译为字节码然后java的正常情况不同 - 解释器逐行解释此字节码将其转换为机器代码并执行)。
此外,下次计算此函数时,将再次执行相同的编译代码,这与正常解释不同,在正常解释中,代码再次逐行解释。这使得执行更快。
答案 4 :(得分:11)
JIT编译器仅在首次执行时将字节代码编译为等效的本机代码。每次连续执行时,JVM仅使用已编译的本机代码来优化性能。
如果没有JIT编译器,JVM解释器会逐行转换字节代码,使其看起来好像正在执行本机应用程序。
答案 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编译器不会将所有代码编译为机器代码。它编译在运行时具有类似模式的代码。
答案 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编译器。
虽然通常在将源代码转换为机器代码时可能会有例外,我们可以使用:
答案 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)
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