Java_JVM_逃逸分析技术_栈上分配_标量替换

什么是逃逸分析(Escape Analysis)?

在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。它跟静态代码分析技术中的指针分析和外形分析类似。

通俗一点讲,当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。

而用来分析这种逃逸现象的方法,就称之为逃逸分析。

举个例子:

 

Java代码     收藏代码
  1. class  A {  
  2. public   static  B b;  
  3.    
  4. public   void  globalVariablePointerEscape() {  // 给全局变量赋值,发生逃逸   
  5. b =  new  B();  
  6. }  
  7.    
  8. public  B methodPointerEscape() {  // 方法返回值,发生逃逸   
  9. return   new  B();  
  10. }  
  11.    
  12. public   void  instancePassPointerEscape() {  
  13. methodPointerEscape().printClassName( this );  // 实例引用传递,发生逃逸   
  14. }  
  15. }  
  16.    
  17. class  B {  
  18. public   void  printClassName(A a) {  
  19. System.out.println(a. class .getName());  
  20. }  
  21. }  

 

 

在这个例子中,一共举了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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值