简述Java编程语言中的逃逸分析

 更新时间:2017年09月11日 10:03:50   作者:wmingstar  
这篇文章主要介绍了简述Java编程语言中的逃逸分析,包括其定义、作用、类型及理论基础等相关内容,十分具有参考价值,需要的朋友可以了解下。

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

1.逃逸分析的定义

        逃逸分析:是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。

        通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

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

        逃逸分析的基本行为就是分析对象的动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用。

        方法逃逸:例如作为调用参数传递到其他方法中。

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

2.逃逸分析的理论基础

        基于 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基于FFmpeg实现Mp4视频转GIF

    Java基于FFmpeg实现Mp4视频转GIF

    FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。本文主要介绍了在Java中如何基于FFmpeg进行Mp4视频到Gif动图的转换,感兴趣的小伙伴可以了解一下
    2022-11-11
  • spring cloud zuul 与 sentinel的结合使用操作

    spring cloud zuul 与 sentinel的结合使用操作

    这篇文章主要介绍了spring cloud zuul 与 sentinel 的结合使用操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java spring事务及事务不生效的原因详解

    Java spring事务及事务不生效的原因详解

    在日常编码过程中常常涉及到事务,在前两天看到一篇文章提到了Spring事务,那么在此总结下在Spring环境下事务失效的几种原因
    2021-09-09
  • 为何修改equals方法时还要重写hashcode方法的原因分析

    为何修改equals方法时还要重写hashcode方法的原因分析

    这篇文章主要介绍了为何修改equals方法时还要重写hashcode方法的原因分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java实现多项式乘法代码实例

    Java实现多项式乘法代码实例

    今天小编就为大家分享一篇关于Java实现多项式乘法代码实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • JSON数据转换成Java对象的方法

    JSON数据转换成Java对象的方法

    就目前来讲,将Java对象转换成JSON对象还是相当简单的,但是 将JSON对象转换成Java对象,就相对比较复杂了些
    2014-03-03
  • SpringBoot2基于重复创建bean的问题及解决

    SpringBoot2基于重复创建bean的问题及解决

    这篇文章主要介绍了SpringBoot2基于重复创建bean的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • SpringBoot中利用AOP和拦截器实现自定义注解

    SpringBoot中利用AOP和拦截器实现自定义注解

    本文将通过拦截器+AOP实现自定义注解,在这里拦截器充当在指定注解处要执行的方法,aop负责将拦截器的方法和要注解生效的地方做一个织入,感兴趣的可以尝试一下
    2022-06-06
  • Java数据类型Integer与int的区别详细解析

    Java数据类型Integer与int的区别详细解析

    这篇文章主要介绍了Java数据类型Integer与int的区别详细解析,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null,int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比,需要的朋友可以参考下
    2023-12-12
  • 使用String转换到Map结构

    使用String转换到Map结构

    这篇文章主要介绍了使用String转换到Map结构,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11

最新评论