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

我总是遇到声称Java被解释的文章。 我知道Oracle的HotSpot JRE提供即时编译,但对于大多数桌面用户来说情况如此吗? 例如,如果我通过以下url下载Java: http : //www.java.com/en/download ,这是否包含JIT编译器?

是的,一点没错。 声称Java被解释的文章通常是由那些不了解Java如何工作或者不理解解释意味着什么的人编写的。

话虽如此,HotSpot有时解释代码 – 这是一件好事。 肯定有任何应用程序的部分(通常在启动时)只执行一次。 如果你可以比JIT编译它更快地解释它,为什么还要花费开销呢? 另一方面,我对“Java被解释”文章的体验是,这不是他们的意思:)

编辑:采取TJ Crowder的观点:是的,从java.com下载的JVM将是HotSpot。 但是HotSpot有两种不同的JIT – 服务器和桌面。 为了总结单句中的差异,桌面JIT旨在快速启动应用程序,而服务器JIT则更侧重于高性能:服务器应用程序通常运行很长时间,所以花费大量时间来优化它们从长远来看,这是值得的。

JVM规范中没有任何内容要求任何特定的执行策略。 有些JVM 只能解释,它们甚至没有编译器。 有些JVM 只有 JIT编译,它们甚至没有解释器。 一些JVM 同时具有解释器和编译器(甚至多个编译器),并在启动时静态选择。 有些人在运行时都有来回动态切换。 有些甚至不是通常意义上的虚拟机,它们只是提前将JVM字节码静态编译为本机机器码。

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

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

C1编译器是一个优化编译器,速度非常快,不会占用大量内存。 C2编译器更加积极地进行优化,但也更慢并且使用更多内存。

您可以通过指定-client-server命令行选项在两者之间进行选择(如果未指定,则指定默认值为-client ),这也会设置一些其他JVM参数,如默认JIT阈值(在客户端模式下,方法将在被解释1500次后编译,在服务器模式下10000次后,可以用-XX:CompileThreshold命令行参数设置)。

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

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

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

  • Java SE HotSpot概览
  • Java HotSpot性能引擎架构
  • 关于Java HotSpot VM的常见问题解答

到目前为止,(最好的)答案似乎都没有回答你的最后一个问题,所以: 是的 ,你从www.java.com下载的Java运行时是Oracle的(Sun的)Hotspot JVM,所以是的,它会做的JIT编译。 HotSpot不仅适用于服务器或类似的东西,它在桌面上运行并充分利用其(非常成熟的)优化JIT编译器。

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