parent
eb422fe576
commit
3238f88899
@ -0,0 +1,23 @@ |
||||
--- |
||||
方法内联 |
||||
--- |
||||
|
||||
#### 概述 |
||||
|
||||
方法内联是指,在编译过程中,当遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。 |
||||
|
||||
方法内联不仅可以消除调用本身带来的性能开销,还可以进一步触发更多的优化。因此,它可以算编译优化里最为重要的一环。 |
||||
|
||||
以 getter/setter 为例,如果没有方法内联,在调用 getter/setter 时,程序需要保存当前方法的执行位置,创建并压入用于 getter/setter 的栈桢、访问字段、弹出栈桢,最后在恢复当前方法的执行。而当内联了对 getter/setter 的方法调用后,上述操作仅剩字段访问了。 |
||||
|
||||
在 C2 和 Graal (它们都是 JIT 编译器)中,方法内联是在解析字节码的过程中完成的。每当碰到方法调用字节码时,C2 将决定是否需要内联该方法调用,如果需要内联,则开始解析目标方法的字节码。 |
||||
|
||||
#### 内联条件 |
||||
|
||||
方法内联能够触发更多的优化。通常而言,内联越多,生成的代码的执行效率越高。然后,,对于编译器来说,内联越多,编译时间就越长,而程序达到峰值性能的时刻也将被推迟。 |
||||
|
||||
因此,即时编译器不会无限制的进行方法内联。 |
||||
|
||||
方法内联有很多规则,除了一些强制内联以及强制不内联的规则外,比如自动拆箱总会被内联,Throwable 类的方法不能被其他类中的方法所内联等,即时编译器会根据方法调用的层数、方法调用指令所在的程序路径的热度、目标方法调用次数及大小,以及当前 IR 图的大小来决定方法调用能否被内联。 |
||||
|
||||
但是,对于虚方法(非 final、static 的方法)而言,即时编译器先要去虚化才能进行方法内联。 |
@ -0,0 +1,9 @@ |
||||
--- |
||||
泛型 |
||||
--- |
||||
|
||||
#### 目录 |
||||
|
||||
1. 思维导图 |
||||
2. |
||||
|
Loading…
Reference in new issue