方法内联

简单理解,就是把目标方法的代码原封不动地“复制”到发起调用的方法之中,

避免发生真实的方法调用而已。

方法内联被称为优化之母,除了消除方法调用的成本之外,更重要的意义是

为其他优化手段建立良好的基础。

细节

实际上大多数的Java方法都是虚方法,编译时无法确定运行时方法的接收者,

也就无法确定方法的版本了。

为了解决虚方法的内联问题,Java虚拟机引入了一种名为类型继承关系分析

Class Hierarchy AnalysisCHA)的技术,这是整个应用程序范围内的

类型分析技术,用于确定在目前已加载的类中,某个接口是否有多于一种的实现、

某个类是否存在子类、某个子类是否覆盖了父类的某个虚方法等信息。

如果是非虚方法,则直接进行内联。否则则向CHA查询此方法在当前程序状态下

是否真的有多个目标版本,如果只有一个,则进行内联(虚拟机假设只有一个),

这种叫做守护内联(Guarded Inling),这种内联属于激进内联,必须预留好

“逃生门”。

假如向CHA查询出来的结果是该方法确实有多个版本的目标方法可供选择,那即时编译器

还将进行最后一次努力,使用内联缓存(Inline Cache)的方式来缩减方法调用的开销。

内联缓存是一个建立在目标方法正常入口之前的缓存,工作原理大致为:在未发生方法调用

之前,内联缓存状态为空,当第一次调用发生之后,缓存记录下方法接收者的版本信息,并且

每次进行方法调用是都比较接收者的版本,如果一样,此时就是一种单态内联缓存(Monomorphic Inline Cache)。

如果出现方法接收者不一致的情况,说明用到了虚方法的多态特性,会退化为超多态内联缓存

Megamorphic Inine Cache),其开销相当于真正查找虚方法表来进行方法分派。