桌面上的JVM是否使用JIT编译?

桌面上的JVM是否使用JIT编译?,jvm,jit,java,Jvm,Jit,Java,我经常看到一些文章声称Java是可解释的。我知道Oracle的HotSpot JRE提供即时编译,但是大多数桌面用户都是这样吗?例如,如果我通过下载Java,这会包括JIT编译器吗?是的,绝对会。声称Java被解释的文章通常是由不理解Java如何工作或不理解解释的含义的人撰写的 话虽如此,HotSpot有时会解释代码——这是一件好事。任何应用程序的某些部分(通常在启动时)都只执行一次。如果您能够以比JIT编译更快的速度解释它,为什么还要为开销而烦恼呢?另一方面,我对“Java被解释”文章的经验是

我经常看到一些文章声称Java是可解释的。我知道Oracle的HotSpot JRE提供即时编译,但是大多数桌面用户都是这样吗?例如,如果我通过下载Java,这会包括JIT编译器吗?

是的,绝对会。声称Java被解释的文章通常是由不理解Java如何工作或不理解解释的含义的人撰写的

话虽如此,HotSpot有时会解释代码——这是一件好事。任何应用程序的某些部分(通常在启动时)都只执行一次。如果您能够以比JIT编译更快的速度解释它,为什么还要为开销而烦恼呢?另一方面,我对“Java被解释”文章的经验是,这不是它们的意思:)


编辑:接受T.J.Crowder的观点:是的,从java.com下载的JVM将成为热点。然而,HotSpot有两种不同的JIT——服务器和桌面。用一句话总结一下不同之处,桌面JIT旨在快速启动应用程序,而服务器JIT则更注重随着时间的推移而提高性能:服务器应用程序通常运行很长时间,因此从长远来看,花在优化它们上的时间确实会带来巨大的回报。

关于Hotspot JVM的一些链接(您在上面的java.com下载链接中下载的内容)可能会有帮助:


到目前为止,这两个(其他方面都很好)答案似乎都没有回答您的最后一个问题,因此:是的,您从www.Java.com下载的Java运行时是Oracle的(Sun的)Hotspot JVM,所以是的,它将进行JIT编译。Hotspot不仅仅用于服务器或类似的东西,它运行在台式机上,并充分利用其(非常成熟的)优化JIT编译器。

JVM规范中没有规定任何特定的执行策略。有些JVM只解释,甚至没有编译器。有些JVM只进行JIT编译,甚至没有解释器。有些JVM既有intepreter也有编译器(甚至有多个编译器)并且在启动时静态地在两者之间进行选择。有些在运行时两者都有并动态地来回切换。有些甚至根本不是通常意义上的虚拟机,它们只是提前静态地将JVM字节码编译成本机机器代码

您正在询问的特定JVM,Oracle的HotSpot JVM,有一个解释器和两个编译器,称为C1和C2编译器,也通俗地称为客户机和服务器编译器,在它们相应的命令行选项之后。HotSpot在解释器和runti的一个编译器之间动态地来回切换me(但它不会在两个编译器之间切换,您必须在命令行上指定其中一个,然后只有该编译器将用于JVM的整个运行时)

根据文档从一些较新的Java SE 7版本开始,一个称为分层编译的新功能开始可用。此功能在开始时使用C1编译器模式以提供更好的启动性能。一旦应用程序正确预热,C2编译器模式将接管以提供更积极的优化而且,通常是更好的性能

C1编译器是一种优化编译器,速度非常快,不占用大量内存。C2编译器的优化更具攻击性,但速度也较慢,占用更多内存

您可以通过指定
-client
-server
命令行选项在两者之间进行选择(
-client
是默认选项,如果不指定一个选项),这还可以设置两个其他JVM参数,如默认JIT阈值(在
-client
模式下,方法解释1500次后将被编译;在
-server
模式下,方法解释10000次后,可以使用
-XX:CompileThreshold
命令行参数进行设置)

“大多数桌面用户”是否会以编译或解释模式运行在很大程度上取决于他们正在运行的代码。我猜想,绝大多数桌面用户都是从Oracle的JRE/JDK或其分支之一(例如OSX上的SoyLatte、Unix/BSD/Linux上的IcedTea或OpenJDK)运行HotSpot JVM的而且他们不需要摆弄命令行选项,因此他们可能会得到默认1500 JIT阈值的C1编译器(但IntelliJ、Eclipse或NetBeans等应用程序有自己的启动程序脚本,通常提供不同的命令行参数)


例如,在我的例子中,我经常运行小脚本,这些脚本实际上从未达到JIT阈值,因此它们从未被编译(也不应该被编译)

Jvm规范从未声明如何执行java字节码,但是,如果使用hotspot VM的Jvm,可以指定JIT编译器,JIT只是一种优化字节码执行的技术。

+1:从我对服务器/客户端Jvm的理解来看:它们实际上是相同的代码,嵌入了不同的参数(客户端JVM可能完全缺少一些优化功能)。这确实是我见过的许多教科书造成的一个巨大困惑,特别是当它们倾向于解释JVM和CLR之间的差异时。这就像它们不顾一切地强调它们之间的一些明显差异,以消除彼此的阴影。我有这个问题,它正在折磨着我,我很高兴我发现了这一点。@Joachimsuer:事实上实际上,
-client
-server
使用两个完全不同的JIT编译器,它们根本不共享太多代码。