JVM优化之逃逸分析(Escape Analysis)

在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。
通俗一点讲,就是当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。

而用来分析这种逃逸现象的方法,就称之为逃逸分析。

举个例子:

Java代码

class A {
    public static B b;  

    public void globalVariablePointerEscape() { // 给全局变量赋值,发生逃逸
        b = new B();
    }  

    public B methodPointerEscape() { // 方法返回值,发生逃逸
        return new B();
    }  

    public void instancePassPointerEscape() {
        methodPointerEscape().printClassName(this); // 实例引用传递,发生逃逸
    }
}  

class B {
    public void printClassName(A a) {
        System.out.println(a.class.getName());
    }

在这个例子中,一共举了3种常见的指针逃逸场景。分别是 全局变量赋值,方法返回值,实例引用传递。
逃逸分析优化JVM原理 我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针。
当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量较多,将给GC带来较大压力,也间接影响了应用的性能。减少临时对象在堆内分配的数量,无疑是最有效的优化方法。
接下来,举一个场景来阐述。
假设在方法体内,声明了一个局部变量,且该变量在方法执行生命周期内未发生逃逸(在方法体内,未将引用暴露给外面)。
按照JVM内存分配机制,首先会在堆里创建变量类的实例,然后将返回的对象指针压入调用栈,继续执行。
这是优化前,JVM的处理方式。
逃逸分析优化 – 栈上分配
优化原理:分析找到未逃逸的变量,将变量类的实例化内存直接在栈里分配(无需进入堆),分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量也被回收。
这是优化后的处理方式,对比可以看出,主要区别在栈空间直接作为临时对象的存储介质。从而减少了临时对象在堆内的分配数量。
逃逸分析另一个重要的优化 – 锁省略
如果通过逃逸分析能够判断出指向某个局部变量的多个引用被限制在同一方法体内,并且所有这些引用都不能“逃逸”到这个方法体以外的地方,那么HotSpot会要求JIT执行一项优化动作 – 将局部变量上拥有的锁省略掉。
这就是锁省略(lock elision)。
性能测试

class DoubleSlot {
    final int value1;
    final int value2;

    public DoubleSlot(int value1, int value2) {
      this.value1 = value1;
      this.value2 = value2;
    }
  }

  static int slotValue(DoubleSlot slot) {
    return slot.value1 + slot.value2;
  }

  static int sum(int[] values) {
    int sum = 0;
    int length = values.length;
    for(int i=1; i<100; i++)
      sum(values);

    for(int i=0; i<100; i++)
      test(values);
  }


测试结果是:
$ /usr/jdk/jdk1.6.0_14/bin/java -server EscapeAnalysisTest
time 8889261
$ /usr/jdk/jdk1.6.0_14/bin/java -server -XX:+DoEscapeAnalysis EscapeAnalysisTest
time 1408140
从结果中,可以看到,启用逃逸分析的运行性能6倍于未启用
JVM中启用逃逸分析 DoEscapeAnalysis安装jdk1.6.0_14,运行java时传递jvm参数  -XX:+DoEscapeAnalysis

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值