java
有一个参数 -XX:MaxInlineLevel
(默认值为 9),它控制内联嵌套调用的最大数量。为什么会有这样的限制?为什么通常基于频率和代码大小的启发式方法不足以让 JVM 自行决定内联的深度?
(这是由 JitWatch 提示的,向我展示了深度嵌套的 Guava checkArgument
调用由于深度而未被内联)
最佳答案
一些重要的搜索揭示了这个有趣的小 fragment (我实际上到达了 Google 搜索的 4 页):
if (inline_depth() > MaxInlineLevel) {
return "inlining too deep";
}
if (method() == callee_method
&& inline_depth() > MaxRecursiveInlineLevel) {
return "recursively inlining too deep";
}
这表明 MaxInlineLevel
正如预期的那样是停止内联之前的深度限制。它还表明 MaxRecursiveInlineLevel
仅指直接递归调用,而不是相互递归调用,例如 foo()
调用 bar()
调用 foo()
。
所以我认为我的猜测评论是正确的 - MaxInlineLevel
是为了防止相互递归,因为要检测到您需要保留对完整深度的引用内联调用堆栈。
MaxInlineResursionLevel
控制 foo()
调用 foo()
内联。
请注意,引用的代码可能不是真正的 JVM。
@apangin 的评论从 Open JDK 8 中找到了一个更现代的热点版本,这表明它现在不再那么简单了。似乎已在整个堆栈中搜索递归调用,因此现在也可能会阻止相互递归超过 MaxRecursiveInlineLevel
。
关于java - 为什么 JVM 有最大内联深度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32503669/