Java_JVM_逃逸分析技术_栈上分配_标量替换
来源:互联网 发布:数据库订单管理模板 编辑:程序博客网 时间:2024/06/05 07:37
什么是逃逸分析(Escape Analysis)?
在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。它跟静态代码分析技术中的指针分析和外形分析类似。
通俗一点讲,当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。
而用来分析这种逃逸现象的方法,就称之为逃逸分析。
举个例子:
- class A {
- 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(A a) {
- System.out.println(a. class .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
资料:
来自: http://www.iteye.com/topic/473355 多谢作者分享!
http://chriszeng87.iteye.com/blog/1278649
http://www.fabiao.net/show.php?contentid=657836
- Java_JVM_逃逸分析技术_栈上分配_标量替换
- JVM的栈上分配与逃逸分析(Escape Analysis)
- Java_逃逸分析技术
- Servlet技术学习_上
- 触发器和pl/sql数据类型_标量
- perl自学2_标量数据_20150313
- 一:PHP语言基础_数据类型_标量数据类型
- 深入分析java web 技术内幕_笔记_一
- 深入分析java web 技术内幕_笔记_二
- 深入分析java web 技术内幕_笔记_三
- 深入分析java web 技术内幕_笔记_四
- 深入分析java web 技术内幕_笔记_五
- 深入分析java web 技术内幕_笔记_六
- 深入分析java web 技术内幕_笔记_七
- 深入分析java web 技术内幕_笔记_八
- 钳形接地电阻测试仪_原理_技术分析
- 2014.7.23 内存分析_栈_堆_栈帧
- 【统计技术】关联分析_推荐系统
- pinyin4j
- Codeforces 691A. Fashion in Berland (模拟)
- java中的内部类
- 树(1)把二叉查找树转换成有序的双向链表
- hdu 5154 Harry and Magical Computer(拓扑排序)
- Java_JVM_逃逸分析技术_栈上分配_标量替换
- 相对布局属性讲解
- 高可用集群的概念理解
- 构造数组的MaxTree
- php set get asset unset
- POJ 1200
- CocoaPods安装和使用
- Ubuntu14.04安装Samba实现文件共享
- hdu 2191