-XX:-TieredCompilation 究竟是做啥的?
Posted
技术标签:
【中文标题】-XX:-TieredCompilation 究竟是做啥的?【英文标题】:What exactly does -XX:-TieredCompilation do?-XX:-TieredCompilation 究竟是做什么的? 【发布时间】:2016-12-07 20:31:46 【问题描述】:使用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,或者根本不编译?
【问题讨论】:
【参考方案1】:-XX:-TieredCompilation
禁用中间编译层 (1、2、3),以便在最大优化级别 (C2) 解释或编译方法。
作为副作用,TieredCompilation
标志还会更改编译器线程数、编译策略和默认代码缓存大小。请注意,禁用TieredCompilation
要禁用 C2 编译器并只保留 C1 而没有额外开销,请设置 -XX:TieredStopAtLevel=1
。
要禁用所有 JIT 编译器并在解释器中运行所有内容,请使用 -Xint
。
【讨论】:
谢谢!现在我有点困惑,因为我有不同的答案:现在设置-XX:-TieredCompilation
(1.) 禁用 C1 并始终编译到最大值 (C2) 或 (2.) 引导 JVM 启发式地决定哪些编译层根据 CPU 禁用(如@AlBlue 所述)?这也让我很难决定接受哪个作为正确答案:P
@MarkusWeninger 我在 AlBlue 的回答下发表了评论。这不是很准确。
谢谢,我刚看到。在第二条评论中,您提到了TierXCompileThreshold
和-XX:CompilationPolicyChoice=2
,这两个我还不知道的新事物,但我会读到它们。 :P 但是第一条评论很好地解释了我的问题。【参考方案2】:
正如您所注意到的,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
【讨论】:
谢谢,-Xint
、-client
和 -server
是我一直在寻找的标志。
如果您想深入兔子洞,我在speakerdeck.com/alblue/hotspot-under-the-hood 中谈到了编译级别:)
谢谢,我去看看! :)
@MarkusWeninger -client
和 -server
标志在现代版本的 JDK 中被忽略。使用-XX:-TieredCompilation
或-XX:TieredStopAtLevel=1
分别禁用C1 或C2。
TierXCompileThreshold
标志不与分层编译一起使用,除非使用 -XX:CompilationPolicyChoice=2
明确选择 SimpleThresholdPolicy。【参考方案3】:
作为 Java 8 用户,建议禁用 TieredComplilation
以用于浮点生产。
Oracle 不会在 Java8 上修复此问题。 所有带 G1GC 的热点 JVM 8 都有相同的问题。
(Bug1) (Bug2)
【讨论】:
从 Java 9 开始修复了错误。 如何禁用分层编译?-XX:-TieredCompilation
你用浮点数做什么?
这些错误已在 8u192 和 8u201 中修复,因此现在可以在 Java 8 中安全使用以上是关于-XX:-TieredCompilation 究竟是做啥的?的主要内容,如果未能解决你的问题,请参考以下文章