Java:JIT方法内联

shr*_*000 15 java jit inline

Java JIT 何时内联方法调用?它是基于#times调用调用方法(如果是,该数字是什么?),或者其他一些标准(那将是什么?)

我已经读过JIT可以内联'final'方法,但它也会根据运行时统计信息内联非最终方法,所以想知道什么是触发条件.

我想答案会因JVM的实现而有所不同,但也许所有这些都有共同之处?

Hot*_*cks 18

简短的回答是它想要的.

通常情况下,JITC会自动内联小型最终或伪终结方法,而无需先收集任何统计数据.这是因为很容易看出内联实际上节省了代码字节与编码调用(或者至少它几乎是"清洗").

除非统计数据表明它是值得的,否则通常不会内联真正的非最终方法,因为如果出现意外的子类,必须以某种方式"保护"内联的非决赛.

至于在JITCed或内联之前调用某些内容的次数,这种情况变化很大,即使在正在运行的JVM中也可能会有所不同.

  • 不是行数.而是,生成的代码的估计字节数(尽管估计可能非常粗略).JITC看不到"行",而是看到"字节码". (4认同)
  • 当JITCing采用更大的方法时,JITC通常会对生成的大小有一个"预算",并且会选择内联直到"预算"填满为止. (2认同)
  • 至于方法有多大"小",通常任何简单设置或返回值("setter"或"getter")的方法都将自动内联,执行简单计算的方法也是如此.(因此"setter"和"getters"是"免费的",它们的存在不会给JITCed代码增加任何执行开销.)JITC可能会或可能不会考虑一个简单的if/then/else方法为"小". (2认同)
  • @SteveKuo - 你知之甚少.如果覆盖的类没有加载YET,那么可以在标记包含的JITCed方法无效后,如果该方法被覆盖,则可以内联该方法.但是,如果JITC避免在某处覆盖已被覆盖的方法,那么它将错过许多良好的优化.因此,如果统计数据显示进入的对象总是(或者甚至通常)是非重写的变种,那么JITC仍然可以选择内联该方法,代价是在某处添加一个警卫.(我在其中一个IBM JITC上工作过.) (2认同)

Nim*_*sky 8

运行服务器的JVM的默认内联阈值Hotspot编译器是35个字节码.

官方文档