Java代码和JIT编译

3

Java代码被编译成字节码,这使得它能在许多平台上移植。但是Java也会进行即时编译,而这是在运行时发生的。

这是否意味着Java需要被编译两次?第一次是由我们编译产生字节码,第二次是由JVM编译吗?谢谢。

5个回答

7

在编译时,您是针对JVM平台进行编译的。然后,在任何计算机上在JVM上运行应用程序时,某些经常使用的代码部分会被编译成本机优化代码。

简而言之:是的,但有很好的理由。


这是正确的;JVM会进一步将代码的部分编译成本地机器代码,以便它可以更快地运行(因为本地机器代码和Java字节码之间不再有抽象)。这种运行时编译的行为被称为即时(JIT)编译。 - Nate W.
只有经常使用的代码才会进行JIT编译吗? 这对我来说是一个新信息,谢谢。 - Chiron
1
更准确地说,字节码被等效的本机代码所替换,而不是重新编译。编译通常比代码替换/优化复杂得多。 - David R Tribble
更准确地说,“某些部分”->“方法”,而“经常使用”->“从系统属性os400.jit.mmi.threshold达到计数”。 - h3xStream

7

如果您的代码足够“热”,JVM可能会将其从字节码编译为本机代码;并且根据程序的运行时特性,它可能会被多次编译,旧版本会被丢弃。

JIT是一个复杂的东西;事实上,Sun JVM有两个JITs(-client和-server),它们之间的行为不同,一些实现甚至支持同时运行这两个JITs(因此,您的应用程序中可能会有解释的字节码与由两个不同的JIT编译的代码并存)。

如果您真的对此主题感兴趣,我建议您阅读更多关于Hotspot(最常见的JIT,因为它是Sun的JIT)的内容。您可以从Sun的页面开始。


为什么它可以被多次编译?第一次编译的字节码不足为奇吗? - Chiron
2
许多因素可能导致JIT放弃旧的编译结果;一些简单的事情,如采用之前从未使用过的不同分支,可能会导致JIT发出"故障"并丢弃旧的代码(该代码是基于每次采用相同分支的情况下生成的)。 - vanza
有时编译器会“预编译”代码,即使该方法之前没有被执行过。然后,当该方法被调用时,它会重新编译为更优化的版本。 - Denis Tulskiy

2
这是否意味着Java被编译两次?第一次是由我们生成字节码,第二次是由JVM进行编译吗?谢谢。 你可以这样说,第一次使用源代码中可用的信息(编译器),然后在运行时(JVM/JIT)当有关特定硬件的信息可用时,以及一些分析来决定哪些内容需要进行JIT编译。涉及到源代码和特定硬件的信息,保留了HTML标签。

1
机制是:
Java -> 字节码(由Java编译器编译)
字节码 -> 本地代码(由JVM解释执行)

0

简短回答:有点是。

最长的回答:这是两件不同的事情。 第一次编译是从源代码到字节码的过程,通常在编译领域中称为中间表示(IR)。

然后虚拟机将字节码转换回本地代码,安装在哪个平台上就在哪个平台上。

这是两种完全不同类型的编译。第二种甚至不算是编译,因为没有语法检查器和作用域分析器……好吧,有一些检查,但不是编译器中所具有的那种检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接