前边讲到了即时编译器将字节码翻译为本地机器码,本文介绍的优化技术是即时编译器在生成代码时采用的代码优化技术
消除方法调用的成本,为其他优化手段建立良好的基础,示例如下,只是举例方法内联的含义,实际优化后肯定不是这样的,还会有其他的优化手段继续优化。
如果能证明一个对象不会逃逸到方法或线程之外与,或者逃逸程度比较低(只逃逸出方法而不会逃逸出线程),则可能为这个对象实例采取不同程度的优化,比如:
:开启逃逸分析
:开启标量替换
:开启同步消除
从JDK6 Update23开始,访问到编译器中开始才默认开启逃逸分析,但目前逃逸分析技术仍在发展之中,未完全成熟。
公共子表达式: 如果一个表达式E之前已经被计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E的这次出现就称为公共子表达式。
?
对于这种表达式,没有必要花时间再对它进行重新计算,只需要直接用前面计算过的表达式结果代替E。
举例:
上面这段代码中的公共子表达式为,Javac编译器不会对这段代码进行任何优化,生成的字节码是完全遵照Java源码的写法直译而成的。
但是当这段代码进入虚拟机的即时编译器后,编译器检测到与是一样的表达式,并且在计算期间b与c的值是不变的,因此这条表达式就可能被视为
有的编译器还可能进行另外一种优化----代数化简,在E本来就有乘法运算的前提下,把表达式变为
我们在访问数组元素的时候肯定遇到过,如果有一个数组foo[],在Java语言中访问数组元素foo[i]的时候徐彤将会自动进行上下界的范围检查,即i必须满足“i>=0 && i<foo.length”的访问条件,否则就会抛出运行时异常。
这样对于开发者的好处就是即时我们没有专门编写防御代码,也能够避免大多数的溢出攻击;对于虚拟机的执行子系统来说,每次数组元素的读写都带有一次隐含的条件判定操作,对于大量数组访问的程序代码,这必定是一种性能负担。
?
但是为了安全这种检查肯定是要做的,但数组边界检查不一定必须在运行期间一次不漏的进行,因此Java将一部分数组边界检查操作放到了编译器,例如:
还有其他消除操作,比如自动装箱消除,安全点消除,消除反射等。
Copyright © 2002-2022 盛煌-盛煌娱乐-盛煌全球注册认证站 版权所有