方法内联
简单理解,就是把目标方法的代码原封不动地“复制”到发起调用的方法之中,
避免发生真实的方法调用而已。
方法内联被称为优化之母,除了消除方法调用的成本之外,更重要的意义是
为其他优化手段建立良好的基础。
细节
实际上大多数的Java
方法都是虚方法,编译时无法确定运行时方法的接收者,
也就无法确定方法的版本了。
为了解决虚方法的内联问题,Java
虚拟机引入了一种名为类型继承关系分析
(Class Hierarchy Analysis
,CHA
)的技术,这是整个应用程序范围内的
类型分析技术,用于确定在目前已加载的类中,某个接口是否有多于一种的实现、
某个类是否存在子类、某个子类是否覆盖了父类的某个虚方法等信息。
如果是非虚方法,则直接进行内联。否则则向CHA
查询此方法在当前程序状态下
是否真的有多个目标版本,如果只有一个,则进行内联(虚拟机假设只有一个),
这种叫做守护内联(Guarded Inling
),这种内联属于激进内联,必须预留好
“逃生门”。
假如向CHA
查询出来的结果是该方法确实有多个版本的目标方法可供选择,那即时编译器
还将进行最后一次努力,使用内联缓存(Inline Cache
)的方式来缩减方法调用的开销。
内联缓存是一个建立在目标方法正常入口之前的缓存,工作原理大致为:在未发生方法调用
之前,内联缓存状态为空,当第一次调用发生之后,缓存记录下方法接收者的版本信息,并且
每次进行方法调用是都比较接收者的版本,如果一样,此时就是一种单态内联缓存(Monomorphic Inline Cache
)。
如果出现方法接收者不一致的情况,说明用到了虚方法的多态特性,会退化为超多态内联缓存
(Megamorphic Inine Cache
),其开销相当于真正查找虚方法表来进行方法分派。