究竟什么-XX:-TieredCompilation呢?

时间:2016-08-02 13:03:47

标签: java jvm jit

使用java -XX:+PrintFlagsFinal我找到了TieredCompilation标志,我在线阅读了一下。

然而,我仍然不知道完全将其设置为false时会发生什么。

我知道编译系统支持5个执行级别,基本上分为解释器,C1和C2:

  • 0级 - 翻译
  • 1级 - 完全优化的C1(无剖析)
  • 级别2 - 带有调用和后备计数器的C1
  • 级别3 - 具有完整性能分析的C1(级别2 + MDO)
  • 等级4 - C2

来源:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/2b2511bd3cc8/src/share/vm/runtime/advancedThresholdPolicy.hpp#l34

两个问题:

(1)通过设置-XX:-TieredCompilation,这些级别中的某些级别是否已禁用?如果是的话,哪个?

(2)是否有一些标志来决定是禁用C1还是C2,还是根本不进行编译?

3 个答案:

答案 0 :(得分:50)

-XX:-TieredCompilation禁用中间编译层(1,2,3),以便在最大优化级别(C2)解释或编译方法。

作为副作用TieredCompilation标志还会更改编译器线程的数量,编译策略和默认代码缓存大小。请注意,禁用TieredCompilation

要禁用C2编译器并仅保留C1而没有额外开销,请设置-XX:TieredStopAtLevel=1

要禁用所有JIT编译器并在解释器中运行所有内容,请使用-Xint

答案 1 :(得分:15)

正如您所注意到的那样,有不同级别的JIT(包括根本没有运行JIT)。

在旧版本的Java中,您以前必须首先选择它们(例如-Xint-client-server)以仅使用解释器运行,只运行客户端(C1 )编译器,或只是服务器(C2)编译器。

Java 7中的分层编译意味着热点编译器可以无缝地在这些步骤之间切换。所以会发生的是,经过一定的运行后,代码将使用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,那么它将使用服务器VM(C2),否则它将使用客户端VM(C1)。

所以-Xint只运行解释器(即没有编译器),你可以分别选择只有-client-server的C1或C2,以及-XX:-TieredCompilation }

答案 2 :(得分:3)

作为Java 8用户,建议禁用TieredComplilation以使用浮点生产。

Oracle不会在Java8上解决这个问题。 所有热点JVM 8 w / G1GC都有同样的问题。

Bug1)(Bug2