我知道Java HotSpot用来决定方法值得内联的标准之一是方法的大小。一方面,这似乎是明智的:如果方法很大,内嵌导致代码膨胀,并且该方法将花费很长时间来执行调用开销是微不足道的。这个逻辑的问题在于,在您决定内联之后,可能会发现,对于这个特定的调用站点,大多数方法都是死代码。例如,该方法可能是一个巨大的switch语句,但大多数调用站点使用编译时常量调用该方法,因此实际上:in-lining是便宜的(不需要整个方法体;最小的代码膨胀)并且有效(方法调用开销主导了实际完成的工作)。
HotSpot是否有任何机制可以利用这种情况并无论如何内联方法,或者是否有一个限制,即使它有一个最小的代码膨胀效应,它甚至会拒绝考虑内联方法?
答案 0 :(得分:4)
HotSpot JIT内联政策相当复杂。它涉及许多启发式方法,如调用方法大小,被调用方法大小,IR节点数,内联深度,调用计数,调用站点数等。
有一些硬限制阻止大型方法内联,包括:
-XX:FreqInlineSize=325
- 要内联的被调用者的字节码的最大大小; -XX:InlineSmallCode=2000
- 如果已经有一个至少以这个大小为单位的编译代码,请不要内联被调用者; -XX:NodeCountInliningCutoff=18000
- 如果解析器生成此数量的IR节点,则停止内联; -XX:DesiredMethodLimit=8000
- 内联后聚合方法的字节码的最大大小。此参数在HotSpot的产品版本中不可调,但可以使用-XX:-ClipInlining
关闭限制。还有其他限制,但正如您已经看到的那样,即使默认情况下启用了-XX:+IncrementalInline
,也不会有很大的内联方法。