Java_逃逸分析技术

转载 2018年04月17日 14:07:35

转自: https://blog.csdn.net/kinger0/article/details/47357333

什么是逃逸分析(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://fantaxy025025.iteye.com/blog/1564472?utm_source=tuicool


Java业务分析实例

-
  • 1970年01月01日 08:00

java虚拟机的逃逸分析

逃逸分析作为其他优化手段提供依据的分析技术,其基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸。甚至还有可能被外部线程...
  • xuqiaobo
  • xuqiaobo
  • 2016-09-14 09:14:40
  • 649

JIT编译器里面的“逃逸分析”(Escape analysis)

逃逸分析是一种编译器后端优化技术,它不是局部优化,而是过程间分析,这意味着它会分析函数调用关系,以判断变量是否“逃逸”出当前作用域范围。 对于JIT类语言来说,一般对象总是堆上分配,逃逸分析是否意味...
  • cteng
  • cteng
  • 2017-08-31 00:39:47
  • 172

JVM的逃逸技术介绍

程序小英雄 2016-12-26 15:42 在Java中每一个对象都有一定的作用域,理论上,一个对象在一块代码中构造,那么也应该在这块代码中被回收,但是实际上,我们经常会让一个对象存活更长...
  • u011277123
  • u011277123
  • 2016-12-28 14:29:40
  • 352

Java中的逃逸分析

大家一般认为new出来的对象都是被分配在堆上,但这并不是完全正确,通过对Java对象分配过程分析,我们发现对象除了可以被分配在堆上,还可以在栈或TLAB中分配空间。而栈上分配对象的技术基础是逃逸分析和...
  • xiaomingdetianxia
  • xiaomingdetianxia
  • 2017-09-01 14:40:56
  • 382

Java之JVM逃逸分析

引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景。概念逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力...
  • blueheart20
  • blueheart20
  • 2017-07-26 23:12:24
  • 3672

JVM的栈上分配与逃逸分析(Escape Analysis)

引言:栈上分配与逃逸分析是在JVM层面进行java性能优化的一个技巧,本文将深入解读其应用以及原理。...
  • blueheart20
  • blueheart20
  • 2016-07-28 00:16:08
  • 3348

JVM优化之逃逸分析(Escape Analysis)

在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析。通俗一点讲,就是当一个对象的指针被多个方法或线程引用时,我们称这个指针发生了逃逸。 而用来分析这种逃逸现象的方法,就称之为逃逸分析。 ...
  • sz_bdqn
  • sz_bdqn
  • 2016-09-01 11:13:05
  • 560

深入分析JVM逃逸分析对性能的影响

逃逸分析(Escape Analysis)逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,称为方法逃逸。甚至还有可能被外部线程访问到,譬如赋值给类变量或可...
  • jijianshuai
  • jijianshuai
  • 2017-06-26 14:53:44
  • 1175

Java中的逃逸分析和TLAB以及Java对象分配

我们在学习使用Java的过程中,一般认为new出来的对象都是被分配在堆上,但是这个结论不是那么的绝对,通过对Java对象分配的过程分析,可以知道有两个地方会导致Java中new出来的对象并一定分别在所...
  • yangzl2008
  • yangzl2008
  • 2015-01-27 21:24:12
  • 11475
收藏助手
不良信息举报
您举报文章:Java_逃逸分析技术
举报原因:
原因补充:

(最多只允许输入30个字)