Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么JVM有一个最大的内联深度?_Java_Jvm_Jit - Fatal编程技术网

Java 为什么JVM有一个最大的内联深度?

Java 为什么JVM有一个最大的内联深度?,java,jvm,jit,Java,Jvm,Jit,java有一个参数-XX:MaxInlineLevel(默认值为9),用于控制内联的最大嵌套调用数。为什么会有这样的限制?为什么基于频率和代码大小的常规启发式不足以让JVM自行决定内联的深度 (这是因为我看到一个嵌套很深的番石榴checkArgument调用由于深度原因没有内联)一些重要的搜索发现了这个有趣的小问题(我实际上已经找到了谷歌搜索的4): 这表明MaxInlineLevel与预期一样是一个硬限制,限制了在停止内联之前的深度。它还建议MaxRecursiveInlineLevel仅指直

java
有一个参数
-XX:MaxInlineLevel
(默认值为9),用于控制内联的最大嵌套调用数。为什么会有这样的限制?为什么基于频率和代码大小的常规启发式不足以让JVM自行决定内联的深度


(这是因为我看到一个嵌套很深的番石榴
checkArgument
调用由于深度原因没有内联)

一些重要的搜索发现了这个有趣的小问题(我实际上已经找到了谷歌搜索的4):

这表明
MaxInlineLevel
与预期一样是一个硬限制,限制了在停止内联之前的深度。它还建议
MaxRecursiveInlineLevel
仅指直接递归调用,而不是相互递归调用,例如
foo()
调用
bar()
调用
foo()

因此,我认为我的猜测是正确的-
MaxInlineLevel
是为了防止相互递归,因为要检测到需要保留对内联调用堆栈全部深度的引用

MaxInlineResursionLevel
控制
foo()
调用
foo()
内联

请注意,引用的代码可能不是真正的JVM


@apangin在OpenJDK8中找到了一个更现代的hotspot版本,这表明它现在已经不再那么简单了。看起来整个堆栈都在搜索递归调用,所以现在可能会阻止相互递归通过
MaxRecursiveInlineLevel

一点也不确定,但可能是为了避免相互递归陷阱,而这种陷阱可能很难/昂贵地用其他方式进行防御。@OldCurmudgeon但是你有MaxRecursiveInlineLevel@MrSimpleMind-有趣-因此,我显然错了。一定是别的原因。你看看那些非常古老的资料。正确的位置在
MaxRecursiveInlineLevel
对两个递归调用进行计数。@apangin-这似乎不像注释所说的那样。此外,它仅与
MaxRecursiveInlineLevel
进行比较。很好的发现,深入挖掘。遍历所有帧,查看被调用方方法是否出现在堆栈上的任何位置。现在设置在InlineTree构造函数中。@apangin,也许你知道这个问题的正确答案?@TagirValeev不完全正确,但我想基本原因是保持简单。无限的内联深度会增加复杂性,编译时间和内存使用可能不太可预测(这对于AOT编译器来说是可以的,但对于JIT来说不是)。还要记住,编译后的代码应该在运行时跟踪整个内联树(以便能够展开和取消优化)。虽然我认为默认值9已经过时了。它已经很久没有改变了,但是现在,有了更多的可用资源,考虑到streams和lamdas,肯定有改进的地方。
    if (inline_depth() > MaxInlineLevel) {
        return "inlining too deep";
    }
    if (method() == callee_method
            && inline_depth() > MaxRecursiveInlineLevel) {
        return "recursively inlining too deep";
    }