You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1.8 KiB
1.8 KiB
方法内联
概述
方法内联是指,在编译过程中,当遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。
方法内联不仅可以消除调用本身带来的性能开销,还可以进一步触发更多的优化。因此,它可以算编译优化里最为重要的一环。
以 getter/setter 为例,如果没有方法内联,在调用 getter/setter 时,程序需要保存当前方法的执行位置,创建并压入用于 getter/setter 的栈桢、访问字段、弹出栈桢,最后在恢复当前方法的执行。而当内联了对 getter/setter 的方法调用后,上述操作仅剩字段访问了。
在 C2 和 Graal (它们都是 JIT 编译器)中,方法内联是在解析字节码的过程中完成的。每当碰到方法调用字节码时,C2 将决定是否需要内联该方法调用,如果需要内联,则开始解析目标方法的字节码。
内联条件
方法内联能够触发更多的优化。通常而言,内联越多,生成的代码的执行效率越高。然后,,对于编译器来说,内联越多,编译时间就越长,而程序达到峰值性能的时刻也将被推迟。
因此,即时编译器不会无限制的进行方法内联。
方法内联有很多规则,除了一些强制内联以及强制不内联的规则外,比如自动拆箱总会被内联,Throwable 类的方法不能被其他类中的方法所内联等,即时编译器会根据方法调用的层数、方法调用指令所在的程序路径的热度、目标方法调用次数及大小,以及当前 IR 图的大小来决定方法调用能否被内联。
但是,对于虚方法(非 final、static 的方法)而言,即时编译器先要去虚化才能进行方法内联。