Skip to content

Latest commit

 

History

History
38 lines (24 loc) · 2.22 KB

08.方法内联.md

File metadata and controls

38 lines (24 loc) · 2.22 KB

方法内联

编译过程中,遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。(即时编译器解析字节码,生成IR图,基于该IR图进行优化,优化是由一个个优化阶段串联起来的(方法内联就是一个优化阶段),每个优化阶段都会对IR图进行转换,最后即时编译器根据IR图的节点以及调度顺序生成机器码)

方法内联的条件:
  • 通常来说,内联越多:

    • 生成的代码执行效率越高
    • 但是对于的即时编译的时间就越长,那么程序达到峰值性能的时刻也将推迟。
    • 生成的机器码越长,JVM会将生成的机器码部署到Code Cache中,但是Code Cache是有大小限制的:
      • -XX:ReservedCodeCacheSize
      • 生成的机器码越长,越容易填满Code Cache,从而出现Code Cache is full, Compiler has been disabled (Code Cache已满,即时编译已被关闭)的警告
  • 所以即时编译器会控制方法内联

    • 自动拆箱总会别内联
    • Throwable类的方法不能被其他类中的方法内联
    • 由 -XX:CompileCommand中的inline指令指定的方法 会被强制内联
      • 由 -XX:CompileCommand 中的 dontinline 指令或 exclude 指令(表示不编译)指定的方法,始终不会被内联
    • 由 @ForceInline注解的方法(仅限JDK内部)会被强制内联
      • 由 @DontInline 注解的方法 (仅限于 JDK 内部方法),始终不会被内联
final修饰符:
  • 即时编译器并不要求目标方法使用final修饰符,只要目标方法事实上是final的,便可以进行相应的去虚化以及内联。
  • 使用了final修饰符,即时编译便可以不用生成对应的假设,并使编译器更加精简,并减少类加载是所需验证的内容。
去虚化:
  • 完全去虚化:
    • 通过类型推导或者类层次分析,将虚方法调用转换为直接调用。关键是证明虚方法调用的目标方法是唯一的,他会为目标方法添加多种假设
  • 条件去虚化:
    • 通过向代码中添加类型比较,将虚方法调用转换为一个个的类型测试以及对于类型的调用。它借助Java虚拟机所收集的类型Profile