Java JVM是如何决定JIT编译一个方法的(将一个方法归类为“hot”的)?
我已经使用过Java JVM是如何决定JIT编译一个方法的(将一个方法归类为“hot”的)?,java,jvm,jit,jvm-hotspot,Java,Jvm,Jit,Jvm Hotspot,我已经使用过-XX:+printcomployment,我知道JIT编译器的基本技术以及使用JIT编译的原因 然而,我仍然没有发现JVM是如何决定JIT编译一个方法的,也就是“何时到了JIT编译方法的适当时机” 我是否正确地假设每个方法都开始被解释,并且只要它没有被归类为“热方法”,它就不会被编译?在我的脑海里,我读到一个方法被执行至少10.000次时被认为是“热的”(在解释了10.000次方法之后,它将被编译),但我不得不承认,我不确定这一点或者我在哪里读到过这一点 因此,总结我的问题: (1
-XX:+printcomployment
,我知道JIT编译器的基本技术以及使用JIT编译的原因
然而,我仍然没有发现JVM是如何决定JIT编译一个方法的,也就是“何时到了JIT编译方法的适当时机”
我是否正确地假设每个方法都开始被解释,并且只要它没有被归类为“热方法”,它就不会被编译?在我的脑海里,我读到一个方法被执行至少10.000次时被认为是“热的”(在解释了10.000次方法之后,它将被编译),但我不得不承认,我不确定这一点或者我在哪里读到过这一点
因此,总结我的问题:
(1) 是否每个方法都被解释为只要它没有被归类为“热”方法(并因此被编译),或者即使它们不是“热”方法,也有理由被编译
(2) JVM如何将方法分为“非热”和“热”方法?执行次数?还有别的吗
(3) 如果“热”方法有某些阈值(如执行次数),是否有Java标志(
-XX:…
)来设置此阈值?控制此阈值的主要参数是-XX:CompileThreshold=10000
Hotspot for Java 8现在默认使用分层编译,使用从级别1到级别4的多个编译阶段。我认为1不是优化。级别3是C1(基于客户端),级别4是C2(基于服务器编译器)
这意味着可以比您预期的更早进行一点优化,并且在达到10K阈值后可以保持很长时间的优化。我所见过的最高级别是在一百万次调用后消除StringBuilder的escape分析
注意:循环多次迭代可能会触发编译器。e、 g.一个10K次的回路就足够了
1) 直到一种方法被认为足够热,它才会被解释。但是,一些JVM(例如Azul Zing)可以在启动时编译方法,您可以强制Hotspot JVM通过内部API编译方法。Java9也可能有一个AOT(提前)编译器,但它仍在研究中
2) 调用数或迭代次数
3) 是
-XX:CompileThreshold=
是主要的编译策略。热点编译策略相当复杂,尤其是对于分层编译,在Java 8中默认情况下是打开的。这既不是执行的次数,也不是CompileThreshold
参数的问题
最好的解释(显然,唯一合理的解释)可以在热点来源中找到,请参阅
我将总结此高级编译策略的要点:
- 执行从第0层(解释器)开始
- 编译的主要触发器有
- 方法调用计数器
李>i
- 后缘计数器
。向后分支通常表示代码中的循环b
- 每当计数器达到某个频率值(
,TierXInvokeNotifyFreqLog
),就会调用一个编译策略来决定下一步如何处理当前运行的方法。根据TierXBackedgeNotifyFreqLog
、i
的值以及C1和C2编译器线程的当前负载,可以决定b
- 继续在解释器中执行李>
- 在解释器中启动评测李>
- 在第3层使用C1编译方法,并提供进一步重新编译所需的完整剖面数据李>
- 在第2层使用C1编译方法,没有配置文件,但有可能重新编译(不太可能)李>
- 最后在第1层用C1编译方法,没有配置文件或计数器(也不太可能)
和tierxinocationthreshold
。可以根据编译队列的长度动态调整给定方法的阈值TierXBackEdgeThreshold
- 编译队列不是FIFO,而是优先级队列
- 带有概要文件数据的C1编译代码(第3层)的行为类似,只是切换到下一层(C2,第4层)的阈值要大得多。例如,一个解释方法可以在大约200次调用后在第3层编译,而C1编译方法在5000多次调用后在第4层重新编译
- 方法内联使用特殊策略。微小的方法可以内联到调用程序中,即使它们不是“热的”。仅当频繁调用较大的方法时(
,InlineFrequencyRatio
)InlineFrequencyCount
编译器阈值以下的方法可能会被认为是热门的。那么这个门槛是什么呢?当一个方法被调用CompilerThreshold
次时,我是否可以排除它被认为是热的?很抱歉接下来的问题,但只是为了让我的术语正确:如果一个方法至少被优化过一次,我是否可以将它称为“热的”,或者这正是“热方法”的定义?@MarkusWeninger这是一个不断更新的东西。如果多次调用同一组代码(但每次调用一次),您可以看到它们并不是一次编译完成的。实际的算法要复杂得多。我认为,获取更多信息的最佳场所是信息源。对于当前JVM,任何其他编写的内容都可能过时。@MarkusWeninger编译是在后台完成的,如果有很多方法可以编译,那么这可能会花费大量的时间。当一个方法成为编译的候选对象时,我会说它是“热门”的。当它被编译并替换现有代码时