---
方法内联
---

#### 概述

方法内联是指，在编译过程中，当遇到方法调用时，将目标方法的方法体纳入编译范围之中，并取代原方法调用的优化手段。

方法内联不仅可以消除调用本身带来的性能开销，还可以进一步触发更多的优化。因此，它可以算编译优化里最为重要的一环。

以 getter/setter 为例，如果没有方法内联，在调用 getter/setter 时，程序需要保存当前方法的执行位置，创建并压入用于 getter/setter 的栈桢、访问字段、弹出栈桢，最后在恢复当前方法的执行。而当内联了对 getter/setter 的方法调用后，上述操作仅剩字段访问了。

在 C2 和 Graal （它们都是 JIT 编译器）中，方法内联是在解析字节码的过程中完成的。每当碰到方法调用字节码时，C2 将决定是否需要内联该方法调用，如果需要内联，则开始解析目标方法的字节码。

#### 内联条件

方法内联能够触发更多的优化。通常而言，内联越多，生成的代码的执行效率越高。然后，，对于编译器来说，内联越多，编译时间就越长，而程序达到峰值性能的时刻也将被推迟。

因此，即时编译器不会无限制的进行方法内联。

方法内联有很多规则，除了一些强制内联以及强制不内联的规则外，比如自动拆箱总会被内联，Throwable 类的方法不能被其他类中的方法所内联等，即时编译器会根据方法调用的层数、方法调用指令所在的程序路径的热度、目标方法调用次数及大小，以及当前 IR 图的大小来决定方法调用能否被内联。

但是，对于虚方法（非 final、static 的方法）而言，即时编译器先要去虚化才能进行方法内联。