什么是逃逸分析

如何快速判断是否逃逸就看方法内new的对象实体是否能够被外部方法进行调用

什么是逃逸分析

在java虚拟机中,对象是在java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析(escape analysis)后发现,一个对象并没有,逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需在堆上分配内存,也无须进行垃圾回收了。这也是最常见的堆外存储技术。

这段蓝色的代码中将创建的 sb 引用作为返回值返回,那么其它线程就有可能拿到这个变量,因为堆是所有线程共享的这就叫发生了逃逸。而下面黄色的代码调用了toString方法底层会重新new一个StringBuffer()出来,这段代码中的sb会在方法结束时就被销毁,因此没有发生逃逸。

逃逸分析代码优化

方法内联

public class test{
  public static void main(string [] args){
    int res = add(1,2);
    }


public int add (int x,int y){
     return x+y;
    }
}


public class test{
  public static void main(string [] args){
   //方法内联,直接使用 add方法内部的逻辑
    int res = 1 + 2;
    }

}

关于逃逸分析的论文在1999年就已经发表了,但直到jdk1.6才有实现,而且这项技术到如今也并不是十分成熟的。其根本原因就是无法保证逃逸分析的性能消耗一定能高于他的消耗。虽然经过逃逸分析可以做标量替换,栈上分配,和锁消除。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。一个极端的例子,就是经过逃逸分析之后,发现没有一个对象是不逃逸的。那这个逃逸分析的过程就白白浪费掉了。虽然这项技术并不十分成熟,但是它也是即时编译器优化技术中一个十分重要的手段。注意到有一些观点,认为通过逃逸分析,jvm会在栈上分配那些不会逃逸的对象,这在理论上是可行的,但是取决于jvm设计者的选择。据我所知,oracle hotspot jvm中并未这么做,这一点在逃逸分析相关的文档里已经说明,所以可以明确所有的
对象实例都是创建在堆上。目前很多书籍还是基于jdk 7以前的版本,jdk已经发生了很大变化,intern字符串的缓存和静态变量曾经都被分配在永久代上,而永久代已经被元数据区取代。但是,
intern字符串缓存和静态变量并不是被转移到元数据区,而是直接在堆上分配,所以这一点同样符合前面一点的结论:对象实例都是分配在堆上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值