通过使用 java -XX:+PrintFlagsFinal,我发现了 TieredCompilation标志,并在网上阅读了一些相关内容。
java -XX:+PrintFlagsFinal
TieredCompilation
然而,我仍然不知道当 没错设置为 false时会发生什么。
false
我知道编译系统支持5个执行级别,基本上分为解释器、 C1和 C2:
资料来源: http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/2b2511bd3cc8/src/share/vm/runtime/advancedThresholdPolicy.hpp#l34
两个问题:
(1)通过设置 -XX:-TieredCompilation,是否禁用了这些级别中的某些级别? 如果是,禁用了哪些级别?
-XX:-TieredCompilation
(2)是否有一些标志来决定是否禁用 C1或 C2,或根本不编译?
正如您所注意到的,JIT 有不同的级别(包括根本不运行 JIT)。
在旧版本的 Java 中,您必须首先选择它们(例如 -Xint、 -client、 -server) ,以便只使用解释器运行,只使用客户端(C1)编译器,或者只使用服务器(C2)编译器。
-Xint
-client
-server
Java7附带的分层编译意味着热点编译器可以在这些步骤之间无缝切换。所以在一定数量的运行之后,代码将用 C1编译,然后在更多的运行之后,它将用 C2编译。这是一个方法一个方法的基础上,所以当一个应用程序正在运行的一个重要部分将只是在解释器下运行(这是为冷代码) ,然后在代码运行了很多(热) ,然后它将被编译为更高性能。您可以通过运行
$ java -XX:+PrintFlagsFinal -version | grep CompileThreshold intx Tier2CompileThreshold = 0 intx Tier3CompileThreshold = 2000 intx Tier4CompileThreshold = 15000 openjdk version "1.8.0_92" OpenJDK Runtime Environment (Zulu 8.15.0.1-macosx) (build 1.8.0_92-b15) OpenJDK 64-Bit Server VM (Zulu 8.15.0.1-macosx) (build 25.92-b15, mixed mode)
-XX:-TieredCompilation基本上是 TieredCompilation=false,这意味着不要做这个转换,你必须事先选择是使用客户端还是服务器编译器。JVM 根据 CPU 启发性地决定应用哪种模式; 如果您有多个处理器或64位 VM,那么它将使用 Server VM (C2) ,否则它将使用 Client VM (C1)。
TieredCompilation=false
因此,-Xint将只使用解释器(即没有编译器)运行,您可以分别使用 -client或 -server选择 C1或 C2,以及 -XX:-TieredCompilation
-XX:-TieredCompilation禁用中间编译层(1、2、3) ,以便在最大优化级别(C2)解释或编译方法。
作为副作用,TieredCompilation标志还会改变编译器线程的数量、编译策略和默认的代码缓存大小。请注意,在禁用 TieredCompilation的情况下
若要禁用 C2编译器并只保留 C1而不增加额外开销,请设置 -XX:TieredStopAtLevel=1。
-XX:TieredStopAtLevel=1
若要禁用所有 JIT 编译器并在解释器中运行所有程序,请使用 -Xint。
作为 Java8用户,建议使用浮点数禁用生产使用的 TieredComplilation。
TieredComplilation
Oracle 不会在 Java8上修复这个问题。 所有热点 JVM 8 w/G1GC 都有相同的问题。
(Bug1)(Bug2)