java有一个参数-XX:MaxInlineLevel(默认值为9),该参数控制对内联的嵌套调用的最大数量。为什么会有这样的限制?为什么基于频率和代码大小的常规启发式方法不足以使JVM自行决定内联的深度?
java
-XX:MaxInlineLevel
(这是由JitWatch提示的,向我显示了checkArgument由于深度而未内嵌深层嵌套的Guava 调用)
checkArgument
一些重要的搜索发现了这个有趣的小片段(我实际上到达了Google搜索的第 4 页):
if (inline_depth() > MaxInlineLevel) { return "inlining too deep"; } if (method() == callee_method && inline_depth() > MaxRecursiveInlineLevel) { return "recursively inlining too deep"; }
这表明,MaxInlineLevel按预期的那样,硬限制是您停止内联之前的深度。这也表明,MaxRecursiveInlineLevel仅指直接递归调用,而不是mutal递归调用,如foo()调用bar()哪个电话foo()。
MaxInlineLevel
MaxRecursiveInlineLevel
foo()
bar()
因此,我认为我的猜测是正确的- MaxInlineLevel防止 相互 递归,因为要检测到您需要保留对内联调用堆栈的整个深度的引用。
MaxInlineResursionLevel控制foo()调用foo()内联。
MaxInlineResursionLevel
请注意,引用的代码可能不是真实的JVM。
@apangin的评论找到了来自Open JDK 8的更现代版本的热点,这表明如今它不再如此简单。似乎在整个堆栈中搜索递归调用,因此现在也可能阻止相互递归MaxRecursiveInlineLevel。