美文网首页Android开发
Java JVM 逃逸分析

Java JVM 逃逸分析

作者: 巴黎没有摩天轮Li | 来源:发表于2020-05-18 23:49 被阅读0次

前言

最近在学习多线程这块内容的时候,了解到了JVM的逃逸分析,现在就简单地记录下。
逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术。这是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

逃逸分析的优化方向

  • 堆分配优化为栈分配
  • 同步省略
  • 标量替换或分离对象

怎么判断是否逃逸

是否逃逸就是判断对象的作用域:当对象在方法中被定义后,如果这个对象被外界所持有并使用。

public static UserInfo setUserInfo(String name, int age) {
   UserInfo userInfo = new UserInfo();
   userInfo.setName(name);
   userInfo.setAge(age);
   return userInfo;
}

UserInfo userInfo是方法中的内部变量,但是以上代码却通过方法参数进行设置姓名与年龄并将该UserInfo对象返回,外界的类XXClass可以调用该方法,并且可以修改该UserInfo类,虽然他是个局部变量,但是逃逸到了方法外部,而且还能够被外部线程访问,因此称之为方法逃逸或线程逃逸。

public static UserInfo setUserInfo(String name, int age) {
   UserInfo userInfo = new UserInfo();
   userInfo.setName(name);
   userInfo.setAge(age);
  // 返回toString
   return userInfo.toString();
}

以上的代码是UserInfo局部变量并未逃逸出方法的写法。

栈分配

首先,提一点基础知识,Java程序在运行期间,在内存中划分5个区域进行存储数据,分别是:寄存器、本地方法区、方法区、堆、栈。和本次博客相关的堆与栈,其中堆用来存放new关键字实例化的对象以及数组,栈用来存放基本数据类型以及局部变量。栈用于保存对象首地址值,并将该变量指向对应的对象存储在堆中的位置。如果发现该对象并没有逃逸出方法,或者线程,那么有可能在栈上进行分配,无需再堆上分配,也就不需要GC了。

同步省略

public String getObj(){
    Object obj = new Object();
    synchronized (obj) {
        String result = createString();
        return result; 
    }
}

以上代码我们在学习多线程的时候,知道这么写是无效锁,因为每次锁锁住的都是新的对象,一个合理的受保护的资源与锁之间的关系应该是N:1,结合逃逸分析,其实这段代码最终会被JIT优化掉, 因为Object对象没有逃逸出方法,对锁对象进行分析只能够被一个线程访问,JIT会取消对这部分代码进行同步,最终优化后的代码:

public String getObj(){
    Object obj = new Object();
    String result = createString();
    return result; 
}

标量替换

所谓标量即不可再进一步分解的量,例如Java基本数据类型就是标量,相反可以被进一步分解的就叫做聚合量,例如Java中创建的对象就是可以进一步分解的聚合量。
同样如果分析一个对象没有逃逸,并且该对象可以进一步进行分解,那么就可以进行标量替换。如下:

private void setLocation(double longitude, double latitude){
    Location location = new Location(longitude, latitude)
}

class Location{
    double longitude;
    double latitude;
    Location(){
        // 省略构造
    }
}

Location对象没有逃逸出方法,而且Location对象是可以拆解成标量,所以JIT不会直接创建Location对象。因此优化后代码如下:

private void setLocation(double longitude, double latitude){
     double longitude = longitude;
     double latitude = latitude;
}
// 被优化掉
class Location{
    double longitude;
    double latitude;
    Location(){
        // 省略构造
    }
}

以上就是所谓的逃逸分析。

相关文章

  • Java JVM 逃逸分析

    前言 最近在学习多线程这块内容的时候,了解到了JVM的逃逸分析,现在就简单地记录下。逃逸分析(Escape Ana...

  • Jvm优化技术

    Jvm优化技术有:逃逸分析、方法内联 一:Jvm优化技术之逃逸分析 1:概念 JVM的优化技术,可以有效减少Jav...

  • Java 逃逸分析

    > 什么是逃逸分析? - 关于 Java 逃逸分析的定义: - 逃逸分析(Escape Analysis)简单...

  • jvm逃逸分析

    首先先看一个问题,对象是否都被分配到了堆内存中? 众所周知java中对象都默认被分配到堆中,在栈中,只保存了对象的...

  • 小师妹学JVM之:逃逸分析和TLAB

    简介 逃逸分析我们在JDK14中JVM的性能优化一文中已经讲过了,逃逸分析的结果就是JVM会在栈上分配对象,从而提...

  • 再清楚不过了,JVM逃逸分析,你一定得知道

    提到JVM,相信大家一定知道JVM是什么?但是,提到逃逸分析,相信大多数人都可能一脸懵逼,逃逸分析到底是什么呢?接...

  • 在金三银四的跳槽季中 你可能缺这一份JVM性能调优总结

    JVM调优配置 -server JVM运行的模式之一, server模式才能进行逃逸分析, JVM运行的模式还有m...

  • JVM的逃逸分析

    对象一定分配在堆中吗? JVM通过逃逸分析,那些逃不出方法的对象会在栈上分配。 什么是逃逸分析? EscapeAn...

  • JVM内存逃逸

    逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术。 逃逸分析的基本行为就是分析对...

  • JVM的逃逸分析

      我们都知道Java中的对象默认都是分配到堆上,在调用栈中,只保存了对象的指针。当对象不再使用后,需要依靠GC来...

网友评论

    本文标题:Java JVM 逃逸分析

    本文链接:https://www.haomeiwen.com/subject/iasmohtx.html