Java中的逃逸问题心得

 更新时间:2018年02月10日 15:42:28   投稿:laozhang  
本篇文章是作者在学习了Java中的逃逸相关知识后的心得分享,一起跟着小编学习下。

大家一般认为new出来的对象都是被分配在堆上,但这并不是完全正确,通过对Java对象分配过程分析,我们发现对象除了可以被分配在堆上,还可以在栈或TLAB中分配空间。而栈上分配对象的技术基础是逃逸分析和标量替换,本文主要介绍下逃逸分析。

逃逸分析的定义

逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。
通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

Java在Java SE 6u23以及以后的版本中支持并默认开启了逃逸分析的选项。Java的 HotSpot JIT编译器,能够在方法重载或者动态加载代码的时候对代码进行逃逸分析。

逃逸分析的基本行为就是分析对象的动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用。
方法逃逸:例如作为调用参数传递到其他方法中。

线程逃逸:有可能被外部线程访问到,譬如赋值给类变量或可以在其他线程中访问的实例变量。

逃逸分析的理论基础

基于 Jong-Deok Choi, Manish Gupta, Mauricio Seffano,Vugranam C. Sreedhar, Sam Midkiff等在论文《Escape Analysis for Java》中描述的算法进行逃逸分析。

该算法引入了连通图,用连通图来构建对象和对象引用之间的可达性关系,并在次基础上,提出一种组合数据流分析法。由于该算法是上下文相关和流敏感的,并且模拟了对象任意层次的嵌套关系,所以分析精度较高,只是运行时间和内存消耗相对较大。

绝大多数逃逸分析的实现都基于“封闭世界(closed world)”的前提:所有可能被执行的,方法在做逃逸分析前都已经得知,并且,程序的实际运行不会改变它们之间的调用关系 。但当真实的 Java 程序运行时,这样的假设并不成立。Java 程序拥有的许多特性,例如动态类加载、调用本地函数以及反射程序调用等等,都将打破所谓“封闭世界”的约定。

逃逸分析之后的处理操作

经过逃逸分析之后,可以得到对象三种可能的逃逸状态:

GlobalEscape(全局逃逸): 即一个对象的引用逃出了方法或者线程。例如,一个对象的引用是复制给了一个类变量,或者存储在在一个已经逃逸的对象当中,或者这个对象的引用作为方法的返回值返回给了调用方法。

ArgEscape(参数级逃逸):即在方法调用过程当中传递对象的应用给一个方法。这种状态可以通过分析被调方法的二进制代码确定。

NoEscape(没有逃逸):一个可以进行标量替换的对象。该对象可以不被分配在传统的堆上。

编译器可以使用逃逸分析的结果,对程序进行优化:

堆分配对象变成栈分配对象:一个方法当中的对象,对象的引用没有发生逃逸,那么这个方法可能会被分配在栈内存上而非常见的堆内存上。

消除同步:线程同步的代价是相当高的,同步的后果是降低并发性和性能。逃逸分析可以判断出某个对象是否始终只被一个线程访问,如果只被一个线程访问,那么对该对象的同步操作就可以转化成没有同步保护的操作,这样就能大大提高并发程度和性能。

矢量替代:逃逸分析方法如果发现对象的内存存储结构不需要连续进行的话,就可以将对象的部分甚至全部都保存在CPU寄存器内,这样能大大提高访问速度。

相关文章

  • Java 替换字符串右侧出现的第一个子串方式

    Java 替换字符串右侧出现的第一个子串方式

    这篇文章主要介绍了Java 替换字符串右侧出现的第一个子串方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • mybatis Reflector反射类的具体使用

    mybatis Reflector反射类的具体使用

    Reflector类是MyBatis反射模块的核心,负责处理类的元数据,以实现属性与数据库字段之间灵活映射的功能,本文主要介绍了mybatis Reflector反射类的具体使用,感兴趣的可以了解一下
    2024-02-02
  • java web实现用户权限管理

    java web实现用户权限管理

    这篇文章主要介绍了java web实现用户权限管理,设计并实现一套简单的权限管理功能,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • IDEA创建Java项目导出Jar包运行

    IDEA创建Java项目导出Jar包运行

    这篇文章主要介绍了IDEA创建Java项目导出Jar包运行,需要的朋友可以参考下
    2021-01-01
  • 在Struts2中的结果集类型

    在Struts2中的结果集类型

    本篇文章,小编为大家介绍关于在Struts2中的结果集类型,有需要的朋友可以参考一下
    2013-04-04
  • Java基础之方法重写详解

    Java基础之方法重写详解

    这篇文章主要介绍了Java基础之方法重写详解,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-05-05
  • springboot自帶线程池ThreadPoolTaskExecutor使用

    springboot自帶线程池ThreadPoolTaskExecutor使用

    本文主要介绍了springboot自帶线程池ThreadPoolTaskExecutor使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • PowerJob的WorkerHealthReporter工作流程源码解读

    PowerJob的WorkerHealthReporter工作流程源码解读

    这篇文章主要为大家介绍了PowerJob的WorkerHealthReporter工作流程源码解读,
    2023-12-12
  • java学习之理解自动拆装箱特性

    java学习之理解自动拆装箱特性

    这篇文章主要介绍java自动拆装箱特性以及java自动拆装箱的应用,有需要的朋友可以借鉴参考下,希望可以有所帮助,祝大家早日升职加薪
    2021-09-09
  • Java如何使用httpclient检测url状态及链接是否能打开

    Java如何使用httpclient检测url状态及链接是否能打开

    这篇文章主要介绍了Java如何使用httpclient检测url状态及链接是否能打开,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论