Skip to content
文章目录

聊聊逃逸分析

什么是逃逸技术

逃逸分析技术是JVM用于提高性能以及节省内存的手段,在JVM编译语境下(JIT阶段),逃逸分析通过以下两个条件判断该对象是否是逃逸的:

  1. 该对象是否分配在堆上(static关键字或者成员变量)
  2. 该对象是否会传给未知代码,比如return到外部给别的类使用。

逃逸技术的两个示例

如下所示,这两段代码就是典型的情况2,将对象传给未知代码,造成逃逸

java
/**
 * @author binghe
 * @description 对象逃逸示例2
 */
public class ObjectReturn{
    public User createUser(){
        User user = new User();
        return user;
    }
}

逃逸分析带来的好处

对象可能分配在栈上

JVM会判断这个对象使用范围,若没有发生逃逸则将对象分配在栈上,这样做的好处就是创建销毁速度会相对快些,而且节省堆区内存,避免GC开销。

分离对象或标量替换

由上文我们知道,对象有可能会被分配在栈上,那么JVM就会将这个对象打散,将对象打散为无数个小的局部变量,这样就方便在栈上分配内存了。

如下所示,若这段代码没有发生逃逸,则JVM会避免创建Point

java
public static void main(String args[]) {
    alloc();
}
class Point {
    private int x;
    private int y;
}
private static void alloc() {
    Point point = new Point(1,2);
    System.out.println("point.x" + point.x + ";point.y" + point.y);
}

代码就会被标量替换,如下所示,避免创建对象,而是用局部变量进行操作。

java
private static void alloc() {
    int x = 1;
    int y = 2;
    System.out.println("point.x = " + x + "; point.y=" + y);
}

同步锁消除

如果JVM分析到这个锁只有一个对象会用到就会将这个锁消除。如下代码JVM看到是字符串拼接操作,就会优化为使用到StringBufferStringBuilder

bash
public static String test03(String s1, String s2, String s3) {
     String s = s1 + s2 + s3;
     return s;
 }

经过逃逸分析发现,是无锁竞争环境,就使用StringBuilder,如下所示

在这里插入图片描述

参考文献

逃逸分析,yyds!!