`
fantaxy025025
  • 浏览: 1329715 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

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

 
阅读更多

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

 

什么是逃逸分析(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

 

+

+
+

=
+

+

+

 

分享到:
评论

相关推荐

    深入JVM系列-逃逸分析、同步省略、栈上分配、标量替换1

    总的来说,逃逸分析是JVM为了提升程序运行效率而采用的一种智能分析技术,它通过对对象的使用范围进行分析,实现同步优化、栈上分配和标量替换等策略,以减少不必要的同步开销和内存分配。理解并掌握逃逸分析,对于...

    JVM 性能调优_JVM 内存区域划分.pdf

    随着 JIT 发展,栈上分配,标量替换优化技术,在堆上分配变得不那么到绝对,只能在 server 模式下才能启用逃逸分析。 在 JVM 中,内存区域的划分和管理对性能优化具有至关重要的影响。正确地理解和管理内存区域可以...

    浅析JVM逃逸的原理及分析

    JVM 逃逸的原理及分析 JVM 逃逸是 Java 虚拟机(JVM)中的一种优化技术,用于减少 Java 程序中的同步...逃逸分析是 JVM 中的一种重要优化技术,可以减少 Java 程序中的同步负载和内存堆分配压力,从而提高程序的性能。

    JVM内存模型及分区 JVM内存模型及分区

    - 对象实例通常在堆上分配,但现代JVM可以通过逃逸分析技术实现栈上分配和标量替换,优化性能。 - 如果堆内存不足,会导致OutOfMemoryError。 5. **方法区(Method Area)/永久代(Permanent Generation)** - ...

    深入了解java中的逃逸分析

    逃逸分析是 Java 虚拟机(JVM)的一种优化技术,通过分析对象的作用域和生命周期,来决定是否对对象进行栈上分配、标量替换、锁消除等优化。逃逸分析的原理是,JVM 通过分析对象的引用情况,来决定对象是否逃逸出...

    1.JVM与Java体系结构

    JIT编译器有多种优化策略,如逃逸分析、标量替换等,以提升程序运行速度。 1.4 类加载机制 JVM采用双亲委派模型进行类加载,当加载类时,会先查找父加载器,如果父加载器无法加载,则由当前加载器尝试加载。这种...

    JVM内存区域划分Java系列2021.pdf

    随着垃圾收集算法的改进,如逃逸分析和标量替换技术,使得对象分配从传统的堆上分配,变为可以使用栈上分配,进一步提高性能。 总结以上各部分,JVM通过划分不同的内存区域,并为每个区域分配明确的职责,保障了...

    揭秘java虚拟机

    深入JVM,我们还需要了解JVM的优化技术,如栈上复用、逃逸分析、标量替换等。这些技术是JIT编译器的重要手段,能够显著提升Java程序的运行效率。例如,栈上复用可以减少对象的创建,提高性能;逃逸分析则可以帮助...

    JVM内存区域划分.docx

    逃逸分析和标量替换是现代JVM优化技术,允许某些对象在栈上分配,以提高效率。逃逸分析判断对象是否可能逃逸出函数作用域,而标量替换则是将对象分解为局部变量分配。堆是垃圾收集的主要关注区域,内存不足时可能...

    JVM工作原理

    为了提升性能,JVM采用了多种优化技术,如逃逸分析、标量替换、栈上替换、内联等。这些技术能帮助JVM更好地理解和优化代码。 7. **工具支持** JVM提供了丰富的工具,如JConsole、VisualVM、JProfiler等,用于监控...

    JVM原理一秒懂,不懂算我输.zip

    2. **栈上分配**:如果对象没有逃逸,可以在栈上直接分配,避免垃圾收集。 3. **标量替换**:将对象的字段拆分成多个基本类型,直接在栈帧中表示,减少内存开销。 了解并熟练掌握JVM原理对于Java开发者至关重要,...

    02-VIP-JVM内存模型深度剖析(1)1

    如果对象不会逃出方法范围,JVM可能会进行栈分配或者标量替换,减少对堆内存的依赖,提高性能。 4. JVM内存参数大小的设置需要根据实际应用的负载和资源需求来调整。以日均百万级订单交易系统为例,我们需要考虑...

    JVM内存模型及方法区

    这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配,但是随着JIT编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导。 5. 方法区(Method Area) 方法区是被所有...

    JAVA模拟器.rar

    4. **性能优化**: Java模拟器通常会进行各种性能优化,如逃逸分析、栈上分配、标量替换等,以提高程序的运行速度。 5. **跨平台兼容性**: Java模拟器的一大特点是其跨平台性。通过JVM,Java程序可以在Windows、...

    JVM虚拟机源码(C++)

    - **优化技术**:了解JIT编译的优化策略,例如逃逸分析、标量替换、循环展开等。 - **错误和异常处理**:JVM如何处理运行时错误和异常,以及如何进行堆栈展开。 通过研究HotSpot源码,开发者可以更好地理解Java程序...

    JVM Hotspot实现源码

    6. **编译和优化策略**:Hotspot使用复杂的优化技术,如逃逸分析、标量替换、循环展开等,来提升代码性能。此外,它还有一套动态适应性优化系统,可以根据运行时数据调整优化级别。 深入理解Hotspot源码,有助于...

    了解Java虚拟机JVM的基本结构及JVM的内存溢出方式

    如果对象仅在方法内部使用,不会被外部引用,那么逃逸分析可能会选择栈上分配或标量替换,提高效率。启用逃逸分析可以通过添加JVM启动参数`-XX:+DoEscapeAnalysis`。 至于内存溢出,常见的有以下几种情况: 1. **...

    笔记,1、虚拟机的前世今生和java内存区域1

    对象分配一般发生在堆上,但通过逃逸分析和标量替换技术,某些对象可能直接在栈上分配,以减少垃圾回收的压力。 总之,理解JVM的内存区域和管理机制对于优化Java应用程序性能至关重要。开发者应熟悉这些概念,以便...

    JVM面试宝典,用30分钟搞明白JVM原理

    11、解释下对象栈上分配、逃逸分析与标量替换 12、判断对象是否是垃圾的引用计数法 13、JVM底层可达性分析算法如何找垃圾对象 14、可达性分析算法中不可达的对象还有机会存活吗 15、什么样的类能被回收 16、解释下...

    【JVM和性能优化】1.Java内存区域

    文章目录了解的必要性JVM历史JVM数据区域私有区共有区内存区域版本变化1.61.71.8元空间栈跟堆Java中的对象都是在堆中分配吗逃逸分析标量替换栈上分配同步消除JVM对象对象创建过程对象内存布局对象访问方式通过句柄...

Global site tag (gtag.js) - Google Analytics