Java 运行时优化

1. 逃逸分析

概念:判断新建的对象是否逃逸,可以使用 -XX:-DoEscapeAnalysis 关闭逃逸分析。

逃逸分析利用的是JVM分层编译,JVM的执行状态分为五个层次:

即时编译器比起解释器多了Code Cache,下次遇到相同的代码直接执行不需要再编译,所以执行后面重复代码会更快。

 

2. 方法内联

如果发现一个方法是热点方法,并且长度不太长时,会进行内联,所谓的内联就是把方法内代码拷贝、粘贴到调用者的位置;

C++有显式的inline关键字。

 

3. 成员变量读取优化

public void test1() {//只要不禁用方法内联,JVM会帮我们优化,只读一次elements.length
    for (int i = 0; i < elements.length; i++) {
        doSum(elements[i]);
    }
} 

public void test2() {//手动优化成局部变量,只读取一次成员变量elements
    int[] local = this.elements;
    for (int i = 0; i < local.length; i++) {
        doSum(local[i]);
    }
}

public void test3() {//foreach也会优化,等价于test2
    for (int element : elements) {
        doSum(element);
    }
}    

 

4. 反射优化

public class Reflect1 {
    public static void foo() {
        System.out.println("foo...");
    } 
    public static void main(String[] args) throws Exception {
        Method foo = Reflect1.class.getMethod("foo");
        for (int i = 0; i <= 16; i++) {
            System.out.printf("%d\t", i);
            foo.invoke(null);
        } 
        System.in.read();
    }
}    

foo.invoke 前面 0 ~ 15 次调用使用的是 MethodAccessor 的 NativeMethodAccessorImpl 实现(性能较低),当调用到第 16 次(从0开始算)时,会采用运行时生成的类代替掉最初的实现(性能变高)

通过debug可以看到这个类叫sun.reflect.GeneratedMethodAccessor1,它里面实现的就是直接调用方法foo而不是反射调用

 

 

 

 
posted @ 2021-03-14 00:02  Kinghao0319  阅读(117)  评论(0编辑  收藏  举报