前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >逃逸分析,yyds!!

逃逸分析,yyds!!

作者头像
冰河
发布2022-06-15 16:58:18
3020
发布2022-06-15 16:58:18
举报
文章被收录于专栏:冰河技术

大家好,我是冰河~~

在JVM的实现中,为了提高JVM的性能和节省内存空间,JVM提供了一种叫做 “逃逸分析” 的特性,而且对于“逃逸分析” 这种特性,也是近年来大厂面试常问的知识点。今天,我们就一起来聊聊什么是逃逸分析

逃逸分析的概念

先以官方的形式来说下什么是逃逸分析。逃逸分析就是:一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针。

在JVM的即时编译语境下,逃逸分析将判断新建的对象是否逃逸。即时编译判断对象是否逃逸的依据:一种是对象是否被存入堆中(静态字段或者堆中对象的实例字段),另一种就是对象是否被传入未知代码。

直接说这些概念,确实有点晕啊,那我们就来两个示例。

对象逃逸示例

一种典型的对象逃逸就是:对象被复制给成员变量或者静态变量,可能被外部使用,此时变量就发生了逃逸。

我们可以用下面的代码来表示这个现象。

代码语言:javascript
复制
/**
 * @author binghe
 * @description 对象逃逸示例1
 */
public class ObjectEscape{
    private User user;
    public void init(){
        user = new User();
    }
}

在ObjectEscape类中,存在一个成员变量user,我们在init()方法中,创建了一个User类的对象,并将其赋值给成员变量user。此时,对象被复制给了成员变量,可能被外部使用,此时的变量就发生了逃逸。

另一种典型的场景就是:对象通过return语句返回。如果对象通过return语句返回了,此时的程序并不能确定这个对象后续会不会被使用,外部的线程可以访问到这个变量,此时对象也发生了逃逸。

我们可以用下面的代码来表示这个现象。

代码语言:javascript
复制
/**
 * @author binghe
 * @description 对象逃逸示例2
 */
public class ObjectReturn{
    public User createUser(){
        User user = new User();
        return user;
    }
}

给出两个示例,相信小伙伴们对JVM的逃逸分析多少有点了解了吧,没错,JVM通过逃逸分析,能够分析出新对象的使用范围,从而决定新对象是否要在堆上进行分配。

还没完,我们继续看下逃逸分析的优点,以便于小伙伴们能够更好的理解逃逸分析。

逃逸分析的优点

逃逸分析的优点总体上来说可以分为三个:对象可能分配在栈上、分离对象或标量替换、消除同步锁。我们可以使用下图来表示。

对象可能分配在栈上

JVM通过逃逸分析,分析出新对象的使用范围,就可能将对象在栈上进行分配。栈分配可以快速地在栈帧上创建和销毁对象,不用再将对象分配到堆空间,可以有效地减少 JVM 垃圾回收的压力。

分离对象或标量替换

当JVM通过逃逸分析,确定要将对象分配到栈上时,即时编译可以将对象打散,将对象替换为一个个很小的局部变量,我们将这个打散的过程叫做标量替换。将对象替换为一个个局部变量后,就可以非常方便的在栈上进行分配了。

同步锁消除

如果JVM通过逃逸分析,发现一个对象只能从一个线程被访问到,则访问这个对象时,可以不加同步锁。如果程序中使用了synchronized锁,则JVM会将synchronized锁消除。

这里,需要注意的是:这种情况针对的是synchronized锁,而对于Lock锁,则JVM并不能消除。

要开启同步消除,需要加上 -XX:+EliminateLocks 参数。因为这个参数依赖逃逸分析,所以同时要打开 -XX:+DoEscapeAnalysis 选项。

所以,并不是所有的对象和数组,都是在堆上进行分配的,由于即时编译的存在,如果JVM发现某些对象没有逃逸出方法,就很有可能被优化成在栈上分配。

衍生出的面试题

其实,针对逃逸分析还会衍生出一些典型的面试题,例如:Java中的对象一定是在堆上分配的吗? 只要我们充分掌握了逃逸分析的原理,回答这种面试题就非常简单了。

关于面试题

Java中的对象一定是在堆上分配的吗?

面试官这样问,如果大家不了解逃逸分析的话,那肯定就有些小伙伴心里会想:我从一开始学习Java时,就知道了:Java中的对象是在堆上创建的,对象的引用是存储到栈中的,那Java中的对象是在堆上分配的啊!难道不是吗?

如果你这样回答,就会被直接Pass掉。

今天,我们介绍完什么是逃逸分析后,相信各位小伙伴就知道如何去完美的回答这道面试题了吧。

面试题解答思路

总体思路上,你可以这样回答:Java中的对象不一定是在堆上分配的,因为JVM通过逃逸分析,能够分析出一个新对象的使用范围,并以此确定是否要将这个对象分配到堆上。

好了,今天就到这儿吧,我是冰河,我们下期见~~

冰河从一名普通程序员,短短几年时间,一路进阶成长为大厂高级技术专家,一直致力于分布式系统架构、微服务、分布式数据库、分布式事务与大数据技术的研究。在高并发、高可用、高可扩展性、高可维护性和大数据等领域拥有丰富的架构经验。对Hadoop,Storm,Spark,Flink等大数据框架源码进行过深度分析,并具有丰富的实战经验。

出版过两本畅销书《海量数据处理与大数据技术实战》、《MySQL技术大全:开发、优化与运维实战》。写了一本《深入理解高并发编程》电子书全网累计下载45W+,发布了一本全网首个开源的以实战案例为背景的《冰河的渗透实战笔记》电子书,全网五星好评。写的文章多次被微信公众号官方推荐。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 冰河技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 逃逸分析的概念
  • 对象逃逸示例
  • 逃逸分析的优点
    • 对象可能分配在栈上
      • 分离对象或标量替换
        • 同步锁消除
        • 衍生出的面试题
          • 关于面试题
            • 面试题解答思路
            相关产品与服务
            大数据
            全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档