JVM逃逸分析,作用及实战案例

一,是什么是逃逸分析?

逃逸分析是分析指针可以存储的所有地方,用于判断指针是否能确保在当前线程。
我理解的就是用来分析,一个对象是否仅在某个线程被访问到。

二,为什么要进行逃逸分析?

在JIT时,进行逃逸分析后,就可以确定对象仅在某一线程中被访问到,这样JIT就可以对其方法进行优化。
包括:
1.堆分配转化为栈分配
2.锁消除
3.分离对象或标量替换
具体方式见下文。

三,判断逃逸的标准有哪些?

1.对象被赋值给堆中的变量或者类的静态变量
2.对象被传进了不确定的代码中运行
下面举几个例子

public class EscapeTest {

    public static Object globalVariableObject;

    public Object instanceObject;

    public void globalVariableEscape(){
        globalVariableObject = new Object(); //静态变量,外部线程可见,发生逃逸
    }

    public void instanceObjectEscape(){
        instanceObject = new Object(); //赋值给堆中实例字段,外部线程可见,发生逃逸
    }
    
    public Object returnObjectEscape(){
        return new Object();  //返回实例,外部线程可见,发生逃逸
    }

    public void noEscape(){
        synchronized (new Object()){
            //仅创建线程可见,对象无逃逸
        }
        Object noEscape = new Object();  //仅创建线程可见,对象无逃逸
    }

}

四,基于逃逸分析的优化

1.堆分配转化为栈分配
如果一个对象的指针不会发生逃逸,那么就可以把该对象分配在栈上,这样在栈帧弹出时回收该对象,不用等到gc时,从而降低gc压力和频率。
2.锁消除
如果一个对象不会发生逃逸,只被一个线程访问,那么在这个对象上的操作就不需要进行同步
3.分离对象或标量替换
如果一个对象不会发生逃逸,可以将该对象分解成一个个基本变量,分配栈上。这样有两点好处,1.不用再生成对象头,从而减少开销。2.空间回收更为高效,同其他栈分配资源。

五,逃逸分析优化案例

1.堆分配转化为栈分配
虚拟机配置参数:-XX:+PrintGC -Xms20M -Xmn20M -XX:+DoEscapeAnalysis

-XX:+DoEscapeAnalysis表示开启逃逸分析,JDK8是默认开启的

-XX:+PrintGC 表示打印GC信息

-Xms20M -Xmn20M 设置JVM内存大小是20M
在这里插入图片描述

public static void main(String[] args){
        for(int i = 0; i < 5_000_000; i++){
            createObject();
        }
    }

    public static void createObject(){
        new Object();
    }

运行结果,没有进行频繁的gc
在这里插入图片描述

将逃逸分析关闭 -XX:-DoEscapeAnalysis
在这里插入图片描述
再次运行
在这里插入图片描述
发生频繁的gc

2.锁消除
虚拟机配置参数:-XX:+PrintGC -Xms500M -Xmn500M -XX:+DoEscapeAnalysis。配置500M是保证不触发GC。
在这里插入图片描述
开启逃逸分析时,用了4毫秒。
注意这个耗时,跟不加锁的上面测试是一致的。

现在关闭逃逸分析再测
在这里插入图片描述
用了111ms。

以上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值