简述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 枚举单例模式及源码分析的实例详解
JAVA 枚举单例模式及源码分析的实例详解 单例模式的实现有很多种,网上也分析了如今实现单利模式最好用枚举,好处不外乎三点: 1.线程安全 2.不会因为序列化而产生新实例 3.防止反射攻击但是貌似没有一篇文章解释ENUM单例如何实现了上述三点,请高手解释一下这三点: 关于第一点线程安全,从反编译后的类源码中可以看出也是通过类加载机制保证的,应该是这样吧(解决) 关于第二点序列化问题,有一篇文章说枚举类自己实现了readResolve()方法,所以抗序列化,这个方法是当前类自己实现的(解决) 关于
-
用Java打印九九除法表代码分析 原创
可能你已经学会了如何在Java中用循环语句打印九九乘法表,但学习是一个需要能够举一反三的事情,接下来,我们就来看看如何使用for循环语句打印九九除法表. 代码(九九除法表): public class TestNineNine { public static void main(String[] args) { for(int b=1;b<=9;b++) { for(int a=1;a<=9;a++) { int c = a*b; System.out.print(c+"/"
-
Java编程中的检查型异常与非检查型异常分析
对于因为编程错误而导致的异常,或者是不能期望程序捕获的异常(解除引用一个空指针,数组越界,除零,等等),为了使开发人员免于处理这些异常,一些异常被命名为非检查型异常(即那些继承自 RuntimeException 的异常)并且不需要进行声明. Checked Exception和Unchecked Exception的几点不同之处 方法签名是否需要声明exception,调用该方法时是否需要捕获exception,exception产生的时候JVM控制程序的状态. Sun 的"T
-
分析java 中AspectJ切面执行两次的原因
分析java 中AspectJ切面执行两次的原因 背景 转眼之间,发现博客已经将近半年没更新了,甚是惭愧.话不多说,正如标题所言,最近在使用AspectJ的时候,发现拦截器(AOP切面)执行了两次了.我们知道,AspectJ是AOP的一种解决方案,本质上是通过代理类在目标方法执行通知(Advice),然后由代理类再去调用目标方法.所以,从这点讲,拦截器应该只会执行一次.但是在测试的时候发现拦截器执行了两次. 问题重现 既然问题已经明了,那么可以通过代码简单重现这个问题,从而更深层次分析到底是什么
-
java注解的全面分析
全面解析java注解 Java中的常见注解 a.JDK中的注解 @Override 覆盖父类或者父接口的方法 @Deprecated 表示方法已经过时 @SuppressWarnings("deprecation") 忽略方法过时警告 b.常见的第三方注解 例如Spring中的@Autowired(自动注入) 注解的分类 a.按照运行机制分 1.源码注解 注解只在源码中存在,编译成class文件就不存在了 2.编译时注解 注解在源码和cl
-
Java正则验证正整数的方法分析【测试可用】
本文实例讲述了Java正则验证正整数的方法.分享给大家供大家参考,具体如下: package des; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Num { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Num p=new Num(); S
-
简述Java编程语言中的逃逸分析
大家一般认为new出来的对象都是被分配在堆上,但这并不是完全正确,通过对Java对象分配过程分析,我们发现对象除了可以被分配在堆上,还可以在栈或TLAB中分配空间.而栈上分配对象的技术基础是逃逸分析和标量替换,本文主要介绍下逃逸分析. 1.逃逸分析的定义 逃逸分析:是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法. 通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上. Java在Java SE
-
Go语言中的逃逸分析究竟是什么?
目录 1.逃逸分析介绍 2.Go中内存分配在哪里? 3.Go与C++内存分配的区别 4.逃逸分析骚操作 5.逃逸分析引申示例说明 1.逃逸分析介绍 学计算机的同学都知道,在编译原理中,分析指针动态范围的方法称之为逃逸分析.通俗来讲,当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了"逃逸". Go语言的逃逸分析是编译器执行静态代码分析后,对内存管理进行的优化和简化,它可以决定一个变量是分配到堆还栈上. 写过C/C++的小伙伴应该知道,使用比较经典的malloc和new函数可以
-
深入了解java中的逃逸分析
逃逸分析 public static StringBuffer craeteStringBuffer(String s1, String s2) { StringBuffer sb = new StringBuffer(); sb.append(s1); sb.append(s2); return sb; } public static String createStringBuffer(String s1, String s2) { StringBuffer sb = new StringBu
-
简述Java编程语言对象的容纳
如果一个程序只含有数量固定的对象,而且已知它们存在的时间,那这个程序是相当简单的. 数组 容纳对象有很多方式,数组是其中最为普遍的一种,它主要有如下两个特点:效率和类型.对于Java来说,为保存和访问一系列对象(实际是对象的句柄),最有效率的方法莫过于数组.数组实际是一个简单的线性序列,因此访问速度非常的快,但是它也存在一些限制,如数组的大小是固定的,并且不可以在"存在时间"内发生改变. 对于基本数据类型构成的数组,其运作类型跟对象数组相似,所不同的是前者里面保存的不是对象的句柄,而是
-
面试中遇到的java逃逸分析问题
前言 记得几年前有一次栈长去面试,问到了这么一个问题: Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在考什么知识点,难道对象不是在堆中分配吗?最后就没然后了,回去等通知了.. 下面我收集了一下网友的回答. 回答很精彩,大家可以加入一起搞技术,我现在将答案总结一下给大家. 什么是逃逸分析? 关于 Java 逃逸分析的定义: 逃逸分析(Escape Analysis)简单来讲就是,Java Hotspot 虚拟机可以分析新创建对象的
-
Java逃逸分析详解及代码示例
概念引入 我们都知道,Java 创建的对象都是被分配到堆内存上,但是事实并不是这么绝对,通过对Java对象分配的过程分析,可以知道有两个地方会导致Java中创建出来的对象并一定分别在所认为的堆上.这两个点分别是Java中的逃逸分析和TLAB(Thread Local Allocation Buffer)线程私有的缓存区. 基本概念介绍 逃逸分析,是一种可以有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法.通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的
-
Go逃逸分析示例详解
目录 引言大纲 逃逸分析 内存管理 栈 堆 堆和栈的对比 加锁 性能 缓存策略 逃逸分析优势 逃逸分析原则 逃逸分析举例 1.参数是interface类型 2. 变量在函数外部有引用 3. 变量内存占用较大 4. 变量大小不确定时 思考题 总结 引言大纲 这个月我会整理分享一系列后端工程师求职面试相关的文章,知识脉络图如下: JAVA/GO/PHP 面试常问的知识点 DB:MySql PgSql Cache: Redis MemCache MongoDB 数据结构 算法 微服务&高并发 流媒体
-
java中jvm逃逸问题分析
引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景. 概念 逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法.通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上. 在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联.当变量(或者对象)在方法中分配后,其
-
简述Java中进程与线程的关系_动力节点Java学院整理
概述 进程与线程,本质意义上说, 是操作系统的调度单位,可以看成是一种操作系统 "资源" .Java 作为与平台无关的编程语言,必然会对底层(操作系统)提供的功能进行进一步的封装,以平台无关的编程接口供程序员使用,进程与线程作为操作系统核心概念的一部分无疑亦是如此.在 Java 语言中,对进程和线程的封装,分别提供了 Process 和 Thread 相关的一些类.本文首先简单的介绍如何使用这些类来创建进程和线程,然后着重介绍这些类是如何和操作系统本地进程线程相对应的,给出了 Java
-
Java中的逃逸问题心得
大家一般认为new出来的对象都是被分配在堆上,但这并不是完全正确,通过对Java对象分配过程分析,我们发现对象除了可以被分配在堆上,还可以在栈或TLAB中分配空间.而栈上分配对象的技术基础是逃逸分析和标量替换,本文主要介绍下逃逸分析. 逃逸分析的定义 逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法. 通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上. Java在Java SE 6u
随机推荐
- Flex 错误(mx.messaging.messages::RemotingMessage)分析
- ionic App 解决android端在真机上tab处于顶部的问题
- javascript操作表格
- smarty模板引擎基础知识入门
- JSP中动态合并单元格的实例代码
- 程序员的表白神器“520”大声喊出来
- asp+Access通用的自动替换数据库中的字符串
- js实现拖拽 闭包函数详细介绍
- 如何在linux系统的host上安装windows系统的guest
- MVC网站开发之权限管理篇
- JAVA按字节读取文件的简单实例
- Android 常见的图片加载框架详细介绍
- Android自定义滚动选择器实例代码
- js中的 || 与 && 运算符详解
- 详解Python二维数组与三维数组切片的方法
- Flutter ListView 上拉加载更多下拉刷新功能实现方法
- MySQL学习(七):Innodb存储引擎索引的实现原理详解
- 解决vscode中golang插件依赖安装失败问题
- Android中的Bitmap序列化失败的解决方法
- jQuery对底部导航进行跳转并高亮显示的实例代码