【发布时间】:2011-02-04 19:36:18
【问题描述】:
我总是遇到声称 Java 被解释的文章。我知道 Oracle 的 HotSpot JRE 提供即时编译,但是对于大多数桌面用户来说是这样吗?例如,如果我通过:http://www.java.com/en/download 下载 Java,这会包含 JIT 编译器吗?
【问题讨论】:
我总是遇到声称 Java 被解释的文章。我知道 Oracle 的 HotSpot JRE 提供即时编译,但是对于大多数桌面用户来说是这样吗?例如,如果我通过:http://www.java.com/en/download 下载 Java,这会包含 JIT 编译器吗?
【问题讨论】:
JVM 规范中没有规定任何特定的执行策略。一些JVM只解释,他们甚至没有有编译器。一些 JVM 仅 JIT 编译,它们甚至没有解释器。一些 JVM both 有一个解释器和一个编译器(甚至是多个编译器),并在启动时在两者之间进行静态选择。有些在运行时同时动态来回切换。有些甚至不是通常意义上的虚拟机根本,它们只是提前将 JVM 字节码静态编译为本机机器码。
您询问的特定 JVM,Oracle 的 HotSpot JVM,有一个解释器和两个编译器,称为 C1 和 C2 编译器,也通俗地称为 client 和 server em> 编译器,在其相应的命令行选项之后。 HotSpot 在运行时动态地在解释器和其中一个编译器之间来回切换 (但它不会在两个编译器之间切换,您必须在命令行中指定其中一个,然后只有那个用于JVM 的整个运行时).
根据文档 here,从一些后来的 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字节码,但是,如果你使用热点VM中的JVM,你可以指定一个JIT编译器,JIT只是一种优化字节码执行的技术。
【讨论】:
是的,当然。声称 Java 是解释型的文章通常由不了解 Java 工作原理或不了解解释型含义的人撰写。
话虽如此,HotSpot 会有时会解释代码 - 这是一件好事。肯定有任何应用程序的一部分(通常在启动时)只执行一次。如果您可以比 JIT 编译它更快地解释它,为什么还要为开销而烦恼呢?另一方面,我对“Java 被解释”文章的体验是,这不是他们的意思:)
编辑:T. J. Crowder 的观点是:是的,从 java.com 下载的 JVM 将是 HotSpot。然而,HotSpot 有两种不同的 JIT——服务器和桌面。一句话总结差异,桌面 JIT 旨在快速启动应用程序,而服务器 JIT 更注重高性能:服务器应用程序通常运行很长时间,因此花费大量时间优化它们从长远来看是有回报的。
【讨论】:
-client 和 -server 使用两个完全不同的 JIT 编译器,它们根本不共享太多代码。
到目前为止,(否则很好的)答案似乎都没有真正回答您的最后一个问题,所以:是的,您从 www.java.com 下载的 Java 运行时是 Oracle 的(Sun 的) Hotspot JVM,所以是的,它会做 JIT 编译。 HotSpot 不仅适用于服务器或类似的东西,它还可以在台式机上运行,并充分利用其(非常成熟的)优化 JIT 编译器。
【讨论】:
其中一些关于 Hotspot JVM 的链接(您在上面的 java.com 下载链接中下载的内容)可能会有所帮助:
【讨论】: