专业的JAVA编程教程与资源

网站首页 > java教程 正文

JVM底层原理之JIT编译器如何通过方法内联优化代码

temp10 2024-09-05 23:35:15 java教程 16 ℃ 0 评论

JVM底层原理之JIT编译器如何通过方法内联优化代码

可能我们对JIT是如何将字节码编译成机器码的过程没多少兴趣,但是我们可以学习一下它采用了哪些优化技术和手段,毕竟它不仅是简单的进行编译,还进行了很多优化的操作。

①方法内联

方法内联介绍:

JVM底层原理之JIT编译器如何通过方法内联优化代码

调用一个方法通常要经历压栈和出栈,如果当前执行的方法又调用了其他方法,就会加大时间和空间的开销。因为如果我们是在方法1的执行途中调用方法2,就需要将程序执行顺序转移到方法2的内存地址,将方法2的内容执行完后,再返回到方法1的位置继续执行。而这需要在执行方法2前,保存好执行到一半的方法1地址和环境,以便执行完方法2后进行恢复现场的工作(可以理解为一种上下文切换的精简版)。

如果一层一层的下去,每层都是一笔开销,而如果我们将方法2的全部代码复制到方法1进行调用的地方,这样在调用方法1时,代码的逻辑没有任何改变,但是却不需要花费嵌套调用的开销了,这就是方法内联。

代码举例:

首先,编译器读取的是字节码.class文件,当然是不可能读取java文件的,但是这里我还是用java代码举了个例子,主要是方便大家理解的是这么个意思的。

进行方法内联前:

//方法1
private int test(int x, int y) {
        int result=add(x,y);
		return result;
}
//方法2
private int add(int s1, int s2) {
		return s1+s2;
}	

方法内联后:

private int test(int x, int y) {
        int result=x+y;
		return result;
}

参数调整:

方法内联不是百分百会被执行的,它会参考方法调用层数,目标方法的调用次数及字节码大小进行判断,我们也可以通过一些参数调整这个优化技术。

说实话我不怎么喜欢贴参数配置,因为80%的人是不需要修改这些配置的,剩下20%在需要修改时会自己去百度。。。而且还要付出自己瞎JB改虚拟机参数的代价(大佬除外)。所以这里主要看看我们可以定制哪些参数就行了,不用记参数指令。

  • 如果方法是经常执行的,方法小于325字节的会进行内联优化,可以用参数-XX:MaxFreqInlineSize=N调整这个字节大小。
  • 如果方法不经常执行,方法小于35字节才会进行内联优化。可以用参数-XX:MaxInlineSize=N调整这个字节大小。
  • -XX:CompileCommand配置中的inline指令指定的方法会被强制内联,dontinline和exclude指定的方法始终不会被内联
  • @ForceInline注解的jdk内部方法会被强制内联,@DontInline注解jdk内部方法始终不会被内联
  • 方法的符号引用未被解析、目标方法所在类未被初始化、或目标方法是native方法,都会导致方法无法内联
  • C2默认不支持9层以上的方法调用(可通过-XX:MaxInlineLevel调整),以及1层的直接递归调用(可通过-XX:MaxRecursiveInlineLevel调整)

另外还有不少其他的jvm参数,就不全贴了,可以自己去查一下,基本上参数名里带inline的都是关于方法内联的参数。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表