什么是内联
内联(Inline) 是一种优化技术,可以将方法的内容直接插入到调用该方法的代码中,从而提高程序的运行速度。
内联前:
public class Main {
public static void main(String[] args) {
invokeMethod();
}
static void invokeMethod() {
System.out.println("Hello, World!");
}
}
main(String[])
方法要等待invokeMethod()
执行结束后才能返回,这样会浪费栈,特别是在某些大型项目上
内联后:
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
怎么内联
C++提供了inline
关键字以提示编译器内联,而Rust提供了#[inline]
属性。Java虽然并没有直接提供相关专用功能,但是有一个内部注释@jdk.internal.vm.annotation.ForceInline
注释签名:
package jdk.internal.vm.annotation;
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
public @interface ForceInline {
}
使用
import jdk.internal.vm.annotation.ForceInline;
public class Main {
public static void main(String[] args) {
invokeMethod();
}
@ForceInline
static void invokeMethod() {
System.out.println("Hello, World!");
}
}
编译输出:
Main.java:1: 错误: 程序包 jdk.internal.vm.annotation 不可见
import jdk.internal.vm.annotation.ForceInline;
^
(程序包 jdk.internal.vm.annotation 已在模块 java.base 中声明, 但该模块未将它导出到未命名模块)
1 个错误
错误: 编译失败
然后再改改编译参数,绕开jdk内部模块的可见性检查,把内部模块全部导入,就能编译成功了:
javac --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED Main.java
需要注意的是,过度使用@ForceInline
可能会导致性能问题。在某些情况下,内联可能会导致代码膨胀和缓存效率降低。
😻恭喜你,你已经掌握了java内联,喜欢就点个赞呗~~~
PS: JVM会在运行时对代码进行分析和优化。所以没有了JIT,GraalVM在AOT编译的Spring反而没有JIT的快,我觉得很大一部分是因为没有inline一些方法