方法逃逸

逃逸的基本行为是分析对象的动态作用域,分析指针动态范围的方法称之为逃逸分析  当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。

逃逸分为方法逃逸线程逃逸

  1. class A {
  2. public static B b;
  3. public void globalVariablePointerEscape() { // 给全局变量赋值,发生逃逸
  4. b = new B();
  5. }
  6. public B methodPointerEscape() { // 方法返回值,发生逃逸
  7. return new B();
  8. }
  9. public void instancePassPointerEscape() {
  10. methodPointerEscape().printClassName(this); // 实例引用传递,发生逃逸
  11. }
  12. }
  13. class B {
  14. public void printClassName(A a) {
  15. System.out.println(a.class.getName());
  16. }
  17. }  不存在逃逸,则可以对这个变量进行优化

        1,栈上分配。
                在一般应用中,不会逃逸的局部对象占比很大,如果使用栈上分配,那大量对象会随着方法结束而自动销毁,垃圾回收系统压力就小很多。
        2,同步消除
                线程同步本身比较耗时,如果确定一个变量不会逃逸出线程,无法被其它线程访问到,那这个变量的读写就不会存在竞争,对这个变量的同步措施
可以清除。
        3,标量替换。
                1, 标量就是不可分割的量,java中基本数据类型,reference类型都是标量。相对的一个数据可以继续分解,它就是聚合量(aggregate)。
                2, 如果把一个对象拆散,将其成员变量恢复到基本类型来访问就叫做标量替换。
                3, 如果逃逸分析证明一个对象不会被外部访问,并且这个对象可以被拆散的话,那么程序真正执行的时候将可能不创建这个对象,而改为直接在>栈上创建若干个成员变量。

相关JVM参数
        -XX:+DoEscapeAnalysis 开启逃逸分析
        -XX:+PrintEscapeAnalysis 开启逃逸分析后,可通过此参数查看分析结果。
        -XX:+EliminateAllocations 开启标量替换
        -XX:+EliminateLocks 开启同步消除
        -XX:+PrintEliminateAllocations 开启标量替换后,查看标量替换情况

时间: 2024-08-07 17:00:40

方法逃逸的相关文章

逃逸分析

[分析对象动态作用域] 方法逃逸,线程逃逸. ——栈上分配:对象可以随着方法的结束而自动销毁. ——同步消除 ——标量替换:将对象中使用到的成员变量恢复原始类型来使用. ======================================================================= 在编程语言的编译优化原理中,分析指针动态范围的方法称之为逃逸分析.它跟静态代码分析技术中的指针分析和外形分析类似. 通俗一点讲,当一个对象的指针被多个方法或线程引用时,我们称这个指针发生

深入理解Java中的逃逸分析

在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. 第一段编译就是javac命令. 在第二编译阶段,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译.很显然,经过解释执行,其执行速度必然会比可执行的二进制字节码程序慢很多.这就是传统的JVM的解释器(Interpreter)的功能.为了解决这种效率问题,引入了 JIT(即时编译)

java虚拟机的逃逸分析

逃逸分析作为其他优化手段提供依据的分析技术,其基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他方法中,称为方法逃逸.甚至还有可能被外部线程访问到,比如赋值给类变量或可以在其他线程中访问的实例变量,称为线程逃逸. 如果能证明一个对象不会逃逸到方法或线程之外,也就是别的方法或者线程无法通过任何途径访问到这个对象,则可能为这个变量进行一些高校的优化. 1)栈上分配,如果确定一个对象不会逃逸出方法之外,那么把这个对象在栈上分配内存,对象所占用

JVM逃逸分析

JDK1.8默认开启逃逸分析,这是一种代码分析手段,能动态分析对象的作用域,为其它优化手段如栈上分配.标量替换和同步消除等提供依据. 一共可能有两种逃逸行为:方法逃逸和线程逃逸. 方法逃逸:当一个对象在方法中定义之后,作为参数传递到其它方法中: 线程逃逸:如类变量或实例变量,可能被其它线程访问到: 如果确认不存在逃逸行为,则可以对该对象进行如下优化:同步消除.标量替换和栈上分配. 参考:https://www.jianshu.com/p/20bd2e9b1f03 原文地址:https://www

JVM优化技术

1.语言无关的经典优化技术之一:公共子表达式消除 公共子表达式消除是一个普遍应用于各种编译器的经典优化技术,它的含义是:如果一个表达式E已经被计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E的这次出现就成为了公共子表达式,对于这种表达式,没有必要花时间再对它进行计算,只需要直接用前面计算过的表达式结果替代E就可以了, 举个例子简单说明它的优化过程,假设有如下代码 int d = (c*b)*12 + a +(a+b*c) 如果这段代码交给javac编译器则不会进行任何优化,

深入理解JAVA虚拟机 晚期(运行期)优化(转载)

这一章节的内容实用性不强 所以不再手打笔记 转载了一篇 原文地址是http://blog.csdn.net/qq_27350929/article/details/54837595 在部分的商用虚拟机中,Java程序最初是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁时,就会把这些代码认定为"热点代码"(Hot Spot Code).为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优

[转]深入理解java虚拟机 精华总结(面试)

原文 http://www.cnblogs.com/prayers/p/5515245.html 一.运行时数据区域 3 1.1 程序计数器 3 1.2 Java虚拟机栈 3 1.3 本地方法栈 3 1.4 Java堆 3 1.5 方法区 3 1.6 运行时常量池 4 二. hotspot虚拟机对象 4 2.1 对象的创建 4 1. 检查 4 2. 分配内存 4 3. Init 4 2.2 对象的内存布局 4 2.3 对象的访问定位 4 1. 使用句柄访问 4 2. 使用直接指针访问 5 三. 

010 晚期(运行期)优化

1.解释器与编译器 整个虚拟机执行架构中,解释器与编译器经常配合工作,如图 分层编译根据编译器编译.优化的规模与耗时,划分出不同的编译层次,其中包括: 第0层,程序解释执行,解释器不开启性能监控功能(Profiling),可触发第1层编译. 第1层,也称为C1编译,将字节码编译为本地代码,进行简单.可靠的优化,如有必要将加入性能监控的逻辑. 第2层(或2层以上),也称为C2编译,也是将字节码编译为本地代码,但是会启用一些编译耗时较长的优化,甚至会根据性能监控信息进行一些不可靠的激进优化. 实施分

晚期(运行期)优化

晚期(运行期)优化 晚期运行期优化 Start HotSpot虚拟机内的即时编译器 几个问题 解释器与编译器 编译对象与触发条件 编译过程 Client Compiler Server Compiler 查看及分析即时编译结果 编译优化技术 公共子表达式消除 数组边界检查消除 方法内联 逃逸分析 Java与CC的编译器对比 ref Start "热点代码"(Hot Spot Code) – 运行特别频繁的方法或代码块:为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本