栈上分配(逃逸分析)

栈上分配(逃逸分析) 分析 【栈上分配(逃逸分析)】? 逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可以能被外部方法所引用,例如作为调用参数传递到其它地方种,称为方法逃逸。
? 甚至还有可能被外部线程访问到,譬如赋值给类变量或者可以在其它线程中访问的实例变量,称为线程逃逸。
逃逸分析 ? 在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。当变量/对象在方法中分配后,其指针有可能被返回或者被全局引用,这样会被其它过程或者线程所引用,这种现象称为指针/引用的逃逸(Escape)。
? 通俗的说,如果一个对象的指针被多个方法或者线程引用时,那么我们成这个对象的指针发生了逃逸。
逃逸的三种状态

  1. 全局逃逸:一个对象的引用掏出了方法或者线程。例如:一个对象的引用赋值给一个类变量,或者这个对象的用引用作为方法的返回这返回给了调用方法。
  2. 参数级逃逸:方法调用过程中,传递对象给另一个方法
  3. 没有逃逸:一个可以进行标量替换的对象,可以将这个对象不分配在传统的堆上
逃逸分析作用
? 通过逃逸分析,java Hotspot 编译器能够分析出一个新的对象的引用的使用范围,从而觉得是否需要将这个对象分配到堆上。
逃逸分析后的优化
  1. 栈上分配:一个方法中的对象,若该对象没有发生逃逸,则可以将这个对象分配在栈上
  2. 消除同步:线程同步的代价是相当高的,同步带来的后果是降低了并发性和程序性能。逃逸分析以判断某个对象是否始终只被一个线程访问,如果只被一个线程访问,那么该对象的同步操作就可以转化为没有同步的操作,这样可以大大提高并发性能
  3. 标量替换:java虚拟机中的原始数据类型(int,long等)都不能在进一步分解,他们就可以成为标量。相对的,如果一个数据可以继续分解,那么他成为聚合量,java中最典型的聚合量就是对象。如果逃逸分析证明一个对象不会被外部访问,并且这个这个对象是可以分解的,那么程序真正执行的时候可能不创建这个对象,而改为直接创建它的若干个被这个方法能够使用到的成员变量来代替。拆散后的变量便可以被单独的分析与优化,可以分别分配在栈帧或者寄存器上,原来的对象就不需要整体被分配在堆中。

    推荐阅读