方法逃逸

逃逸的基本行为是分析对象的动态作用域,分析指针动态范围的方法称之为逃逸分析  当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。

逃逸分为方法逃逸线程逃逸

  1. class A {  
  2. public static B b;  
  3.    
  4. public void globalVariablePointerEscape() { // 给全局变量赋值,发生逃逸  
  5. b = new B();  
  6. }  
  7.    
  8. public B methodPointerEscape() { // 方法返回值,发生逃逸  
  9. return new B();  
  10. }  
  11.    
  12. public void instancePassPointerEscape() {  
  13. methodPointerEscape().printClassName(this); // 实例引用传递,发生逃逸  
  14. }  
  15. }  
  16.    
  17. class B {  
  18. public void printClassName(A a) {  
  19. System.out.println(a.class.getName());  
  20. }  
  21. }  不存在逃逸,则可以对这个变量进行优化

        1,栈上分配。
                在一般应用中,不会逃逸的局部对象占比很大,如果使用栈上分配,那大量对象会随着方法结束而自动销毁,垃圾回收系统压力就小很多。
        2,同步消除
                线程同步本身比较耗时,如果确定一个变量不会逃逸出线程,无法被其它线程访问到,那这个变量的读写就不会存在竞争,对这个变量的同步措施
可以清除。
        3,标量替换。
                1, 标量就是不可分割的量,java中基本数据类型,reference类型都是标量。相对的一个数据可以继续分解,它就是聚合量(aggregate)。
                2, 如果把一个对象拆散,将其成员变量恢复到基本类型来访问就叫做标量替换。
                3, 如果逃逸分析证明一个对象不会被外部访问,并且这个对象可以被拆散的话,那么程序真正执行的时候将可能不创建这个对象,而改为直接在>栈上创建若干个成员变量。

相关JVM参数
        -XX:+DoEscapeAnalysis 开启逃逸分析
        -XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。
        -XX:+EliminateAllocations 开启标量替换
        -XX:+EliminateLocks 开启同步消除
        -XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况

posted @ 2017-08-25 21:47  yangbk  阅读(1980)  评论(0编辑  收藏  举报