逃逸分析----在计算机语言编译器语言优化管理中,分析指针动态范围的方法称之为逃逸分析(通俗点讲,当一个对象的指针被多个方法或线程引用时)---我们称这个指针发生了逃逸。
- public class G {
- public static B b;
- public void globalVariablePointerEscape(){//给全局变量赋值,发生逃逸
- b=new B();
- }
- public B methodPointerEscape(){//方法返回值,发生逃逸
- return new B();
- }
- public void instancePassPointerEscape(){
- methodPointerEscape().printClassName(this);//实例引用发生逃逸
- }
- }
- class B{
- public void printClassName(G g){
- System.out.println(g.getClass().getName());
- }
- }
在这个例子中,一共举了3种常见的指针逃逸场景。分别是 全局变量赋值,方法返回值,实例引用传递。
逃逸分析优化JVM原理
我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针。
当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量较多,将给GC带来较大压力,也间接影响了应用的性能。减少临时对象在堆内分配的数量,无疑是最有效的优化方法。
怎么减少临时对象在堆内的分配数量呢?不可能不实例化对象吧!
场景介绍
其实,在java应用里普遍存在一种场景。一般是在方法体内,声明了一个局部变量,且该变量在方法执行生命周期内未发生逃逸(在方法体内,未将引用暴露给外面)。
按照JVM内存分配机制,首先会在堆里创建变量类的实例,然后将返回的对象指针压入调用栈,继续执行。
这是优化前,JVM的处理方式。
逃逸分析优化 - 栈上分配
优化原理:分析找到未逃逸的变量,将变量类的实例化内存直接在栈里分配(无需进入堆),分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收。
这是优化后的处理方式,对比可以看出,主要区别在栈空间直接作为临时对象的存储介质。从而减少了临时对象在堆内的分配数量。
逃逸分析的原理很简单,但JVM在应用过程中,还是有诸多考虑。
比如,逃逸分析不能在静态编译时进行,必须在JIT里完成。原因是,与java的动态性有冲突。因为你可以在运行时,通过动态代理改变一个类的行为,此时,逃逸分析是无法得知类已经变化了。
逃逸分析另一个重要的优化 - 同步消除
如果你定义的类的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。
性能测试
来自http://blog.uncommons.org/性能测试结果。
测试场景1:
生成几百万个随机数,然后做一些少量运算。
VM 参数: -server
95 秒
VM 参数: -server -XX:+DoEscapeAnalysis
73 秒
性能提高: 23%
测试场景2:
非负矩阵分解算法。
VM 参数: -server
22.6 秒
VM 参数: -server -XX:+DoEscapeAnalysis
20.8 秒
性能提升: 8%
JVM中启用逃逸分析 DoEscapeAnalysis
安装jdk1.6.0_14,运行java时传递jvm参数 -XX:+DoEscapeAnalysis
逃逸分析还能用于以下优化场景,但在JVM中未知使用。
1,标量替换(Scalar Replacement)
2,减小竞争检测范围
3,基于区域的内存分配
…...
参考资料:
http://www.cag.csail.mit.edu/~rinard/pointer_and_escape_analysis/
http://developer.amd.com/documentation/Articles/pages/01302008_jvm.aspx
http://en.wikipedia.org/wiki/Escape_analysis
http://en.wikipedia.org/wiki/Java_performance#Escape_analysis_and_lock_coarsening
http://staff.ustc.edu.cn/~yuzhang/papers/cncc07.pdf(一种实现方法,过于学术,不过引言部分写得很不错)
http://java.dzone.com/articles/escape-analysis-java-6-update
http://en.wikipedia.org/wiki/Non-negative_matrix_factorization
相关推荐
在开放世界实现逃逸分析算法,史晓华,金茂忠,逃逸分析(escape analysis)是一种可以有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法.此前绝大多数逃逸分析的��
开放世界逃逸分析算法中的优化和反优化问题,史晓华,吴甘沙,本文介绍了在开放世界实现逃逸分析算法时,如何进行优化和反优化的处理技术。本文介绍的相关方法已经在Open Runtime Platform上进行了实
主要介绍了面试中遇到的java逃逸分析问题,逃逸分析(Escape Analysis)简单来讲就是,Java Hotspot 虚拟机可以分析新创建对象的使用范围,并决定是否在 Java 堆上分配内存的一项技术。,需要的朋友可以参考下
编译 apr 1.7.0 需要的头文件 apr_escape_test_char.h --------------------- /* this file is automatically generated by gen_test_char, do not edit. "make include/private/apr_escape_test_char.h" to ...
Escape
易语言Escape加解密源码,Escape加解密,unescape,escape
易语言取Escape编码源码,取Escape编码,十到十六,Escape编码,URL编码,ANSI转UNICODE,MultiByteToWideChar
java实现js的escape和unescape方法
EscapeHTML 是一个简单的 Swift 库用来对 HTML 中的特殊字符进行转义。 示例代码: import EscapeHTML escape("<p>some html</p>") 标签:EscapeHTML
xe5 android Escape UnicodeString to String utf8 json Escape
易语言源码易语言Escape加解密源码.rar 易语言源码易语言Escape加解密源码.rar 易语言源码易语言Escape加解密源码.rar 易语言源码易语言Escape加解密源码.rar 易语言源码易语言Escape加解密源码.rar 易语言源码...
A520_escape
System.out.println(escape(stest)); System.out.println(unescape(escape(stest))); 输出结果: 中文1234 abcd[](),.~\ %u4E2D%u65871234+abcd%5B%5D()%3C%2B%3E%2C.~%5C 中文1234 abcd[](),.~\
Java文本字符编码解码操作类 Escape.java源代码
易语言取Escape编码源码。@易语言源码分享站。
escape关闭bootstrap响应式弹出层
org.unbescape.html.HtmlEscape 找不到 添加这个包就欧克辣
FORD福特锐际ESCAPE车型手册汽车说明书pdf电子版下载
RegExp.escape, 将 RegExp.escape 添加到ECMAScript标准的建议 RegExp.escape 建议将 RegExp.escape 方法添加到ECMAScript标准的建议。形式规范状态这里建议是一个阶段 0 ( 说明) 提案,正在等待实现和更多输入。 ...
escape_velocity