你真的了解逃逸分析(Escape Analysis)么?

什么是逃逸?

逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到;这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量引用。正常的方法调用中,方法体中创建的对象将在执行完毕之后,将回收其中创建的对象;故由于无法回收,即成为逃逸。

作用

java Hotspot 编译器能够分析出一个新的对象的引用的使用范围,从而觉得是否需要将这个对象分配到堆上。

例子

    /**
     * 无逃逸
     */
    void test01() {
        String test1 = "test1";
    }
    String test2;

    /**
     * 逃逸
     */
    void test02() {
        test2 = "test2";
    }

在方法内的变量不会逃逸,在方法外声明的对象会发生逃逸,脱离了方法的控制,方法结束时变量没有结束

分类

方法逃逸:

  • 定义
    一个对象在方法中被定义,但却被方法以外的其他代码使用。
  • 场景
    如传参到其他方法中等可能导致此情况发生。

线程逃逸:

  • 定义
    一个对象由某个线程在方法中被定义,但却被其他线程访问。
  • 场景
    如类变量、公用的或有get、set方法的实例变量等

三种状态

全局逃逸:

一个对象的引用掏出了方法或者线程。例如:一个对象的引用赋值给一个类变量,或者这个对象的用引用作为方法的返回这返回给了调用方法。

参数级逃逸:

方法调用过程中,传递对象给另一个方法

没有逃逸:

一个可以进行标量替换的对象,可以将这个对象不分配在传统的堆上

参数设置

-XX:+DoEscapeAnalysis	//使用 (JDK8中,逃逸分析默认开启。)
-XX:-DoEscapeAnalysis	//不用
-XX:+PrintEscapeAnalysis //结果展示

逃逸分析能不能在编译期间进行呢?

首先需要弄清楚两个概念,静态编译和动态编译

静态编译指的是javac之类的编译,动态编译指的是JIT等即时编译。

因为Sun公司不在对javac这方面的进行优化。所以优化基本上都是在JVM中,

通过查询资料得到

Excelsior JET 这个东西要比我们主流的HOTSPOT更早实现了逃逸分析和相关优化,

但是不知道Java在运行期间不知道会 加载上什么代码。Java有很多的小方法,虚方法的调用,难以进行静态分析。

同时逃逸分析需要 在比较大的代码快中工作才会比较有效。因为编译器需要了解更多的代码。用于更加准确的判断对象有没有逃逸,

只在小块代码上分析的话,很多的时候都得到错误的判断,就没有效果了。

结论:

逃逸分析可以在编译期运行,但是由于技术上面的一些原因,所以是在运行期间进行的比较多。

怎么判断一个对象是不是会逃逸?(过程)

对数据流敏感的一系列的分析,从而确定能够程序各个分支执行对这个对象的影响,耗时较长

那么逃逸分析有什么优化技术呢?

栈上分配:

普通对象在堆中分配,各线程共享。但有GC消耗。

当确定对象不会发生方法逃逸时,可在线程栈上分配对象。此时对象生命周期和方法相同,随栈帧出栈时即可销毁,不需要GC了。

同步消除:

线程同步降低了并发性和程序性能。

锁消除:当确定对象不会发生线程逃逸时,可消除该对象不必要的同步操作(永不会竞争)。具体来说,JVM在编译器运行时会扫描代码,当检查到那些不可能存在共享区竞争,但却有互斥同步的代码,直接将这样的多此一举的同步消除

锁粗化:JVM针对那些反复在一段代码中对同一对象加锁的情况,将同步锁放在最外层包住这里面的多次同步锁,同时取消内部的同步锁

标量替换:

标量是指一个数据无法分解成更小的数据,基础类型的数据都算是标量,对象可以被分解成其他的成员变量,所以说变量不是

标量,那么标量替换是指在运行期间,不必要创建对象,而是改成创建对象的成员变量,不仅可以让对象成员在栈上分配和读写之外,还

可以为后一步的优化技术创造了条件。

现存问题

无法保证逃逸分析的收益大于进行此操作带来的性能消耗。所以JVM目前采用不准确、时间较短算法进行逃逸分析,以权衡收益和开销。

如果大家对java架构相关感兴趣,可以关注下面公众号,会持续更新java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达, 超神之路从此展开, BTAJ不再是梦想!

架构殿堂

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The-Venus

您的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值