如果Java中的大部分都是调用站点的死代码,那么java可以内联一个大方法吗?

时间:2018-05-02 19:00:10

标签: java jvm compiler-optimization jit jvm-hotspot

我知道Java HotSpot用来决定方法值得内联的标准之一是方法的大小。一方面,这似乎是明智的:如果方法很大,内嵌导致代码膨胀,并且该方法将花费很长时间来执行调用开销是微不足道的。这个逻辑的问题在于,在您决定内联之后,可能会发现,对于这个特定的调用站点,大多数方法都是死代码。例如,该方法可能是一个巨大的switch语句,但大多数调用站点使用编译时常量调用该方法,因此实际上:in-lining是便宜的(不需要整个方法体;最小的代码膨胀)并且有效(方法调用开销主导了实际完成的工作)。

HotSpot是否有任何机制可以利用这种情况并无论如何内联方法,或者是否有一个限制,即使它有一个最小的代码膨胀效应,它甚至会拒绝考虑内联方法?

1 个答案:

答案 0 :(得分:4)

HotSpot JIT内联政策相当复杂。它涉及许多启发式方法,如调用方法大小,被调用方法大小,IR节点数,内联深度,调用计数,调用站点数等。

有一些硬限制阻止大型方法内联,包括:

  • -XX:FreqInlineSize=325 - 要内联的被调用者的字节码的最大大小;
  • -XX:InlineSmallCode=2000 - 如果已经有一个至少以这个大小为单位的编译代码,请不要内联被调用者;
  • -XX:NodeCountInliningCutoff=18000 - 如果解析器生成此数量的IR节点,则停止内联;
  • -XX:DesiredMethodLimit=8000 - 内联后聚合方法的字节码的最大大小。此参数在HotSpot的产品版本中不可调,但可以使用-XX:-ClipInlining关闭限制。

还有其他限制,但正如您已经看到的那样,即使默认情况下启用了-XX:+IncrementalInline,也不会有很大的内联方法。