What exactly does -XX:-TieredCompilation do?
使用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,或者根本不编译?
-XX:-TieredCompilation禁用中间编译层(1、2、3),以便在最大优化级别(C2)处解释或编译方法。
副作用TieredCompilation标志还更改了编译器线程数,编译策略和默认代码缓存大小。请注意,禁用TieredCompilation
-
编译器线程将减少;
-
将选择简单的编译策略(基于方法调用和后端计数器),而不是高级的编译策略;
-
默认的保留代码缓存大小将小5倍。
要禁用C2编译器并仅保留C1而没有额外的开销,请设置-XX:TieredStopAtLevel=1。
要禁用所有JIT编译器并在解释器中运行所有程序,请使用-Xint。
-
谢谢!现在我有点困惑,因为我有不同的答案:现在将设置-XX:-TieredCompilation(1.)禁用C1并始终编译为最大(C2)或(2.)导致JVM试探性地决定基于哪个编译层禁用在CPU上(如@AlBlue所述)?这也使我难以决定,哪一个才是正确答案:P
-
@MarkusWeninger Ive在AlBlues答案下发表了评论。它不是很准确。
-
谢谢,我刚刚看到了。在第二个注释中,您提到了TierXCompileThreshold和-XX:CompilationPolicyChoice=2,这是我仍然不知道的两个新事物,但是我将阅读它们。 :P但是第一个评论很好地解释了我的问题。
您已经注意到,JIT有不同的级别(包括完全不运行JIT)。
在较旧的Java版本中,您通常必须首先选择它们(例如-Xint,-client,-server),以便仅使用解释器,仅使用客户端(C1)编译器或仅使用服务器(C2)运行)编译器。
Java 7附带的分层编译意味着热点编译器可以在这些步骤之间无缝切换。因此,发生的情况是,经过一定数量的运行后,将使用C1编译代码,然后再运行C2,则将对其进行编译。这是基于方法的,因此,当应用程序运行时,很大一部分将仅在解释器下运行(用于冷代码),然后在大量运行(热代码)后将其编译为表现更好。您可以通过运行来查看不同的级别
1 2 3 4 5 6 7
| $ 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
-
谢谢,-Xint,-client和-server是我一直在寻找的标志。
-
如果您想深入研究兔子漏洞,我在speakerdeck.com/alblue/hotspot-under-the-hood中谈到了一些编译级别:)
-
谢谢,我来看看! :)
-
@MarkusWeninger -client和-server标志在现代JDK版本中只是被忽略。使用-XX:-TieredCompilation或-XX:TieredStopAtLevel=1分别禁用C1或C2。
-
除非使用-XX:CompilationPolicyChoice=2明确选择了SimpleThresholdPolicy,否则TierXCompileThreshold标志不会与分层编译一起使用。
作为Java 8用户,建议禁用TieredComplilation以用于带浮点的生产环境。
Oracle不会在Java8上解决此问题。
所有带有G1GC的热点JVM 8都有相同的问题。
(错误1)(错误2)
-
自Java 9起,错误已修复。
-
以及如何禁用tieredCompilation? -XX:-TieredCompilation,您对浮点数使用什么?
-
这些错误已在8u192和8u201中修复,因此现在可以在Java 8中安全使用