引言: 逃逸分析(Escape Analysis)是众多JVM技术中的一个使用不多的技术点,本文将通过一个实例来分析其使用场景。

概念

逃逸分析,是一种可以有效减少Java 程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。通过逃逸分析,Java Hotspot编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。

Java在Java SE 6u23以及以后的版本中支持并默认开启了逃逸分析的选项。Java的 HotSpot JIT编译器,能够在方法重载或者动态加载代码的时候对代码进行逃逸分析,同时Java对象在堆上分配和内置线程的特点使得逃逸分析成Java的重要功能。

上面的这段话是我引用别人的一段话,文中使用了大量的专业术语,我总结一下它的意思就是:

通过逃逸分析来决定某些实例或者变量是否要在堆中进行分配,如果开启了逃逸分析,即可将这些变量直接在栈上进行分配,而非堆上进行分配。这些变量的指针可以被全局所引用,或者其其它线程所引用。

开启设置

默认的在JDK 6u23以上是默认开启,这里将设置重新明确一下:

强制开启:

-server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

关闭逃逸分析:

-server -XX:-DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m

实例验证

代码:

public class OnStackTest {
    public static void alloc() {
        byte[] b = new byte[2];
        b[0] = 1;
    }

    public static void main(String[] args) {
        long b = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            alloc();
        }
        long e = System.currentTimeMillis();
        System.out.println(e - b);
    }
}

开启逃逸的运行结果:

未开启逃逸分析的运行结果:

分析一下,这里是将2个字节的数据循环分配1千万次,开启逃逸的运行时间为8milisecond, 而未开启则为956, 为未开启的将近1/120.

差异效果还是非常明显的…..

总结

栈上的空间一般而言是非常小的,只能存放若干变化和小的数据结构,大容量的存储结构是做不到。这里的例子是一个极端的千万次级的循环,突出了通过逃逸分析,让其直接从栈上分配,从而极大降低了GC的次数,提升了程序整体的执行效能。

所以,逃逸分析的效果只能在特定场景下,满足高频和高数量的容量比较小的变量分配结构,才可以生效。

———————- 无聊的分割线,终于到底了——————–

Java之JVM逃逸分析的更多相关文章

  1. 深入理解Java中的逃逸分析

    在Java的编译体系中,一个Java的源代码文件变成计算机可执行的机器指令的过程中,需要经过两段编译,第一段是把.java文件转换成.class文件.第二段编译是把.class转换成机器指令的过程. ...

  2. java中的逃逸分析

    逃逸分析 public static StringBuffer craeteStringBuffer(String s1, String s2) { StringBuffer sb = new Str ...

  3. JVM逃逸分析

    开启逃逸分析: -server -XX:+DoEscapeAnalysis -XX:+PrintGCDetail -Xmx10m -Xms10m 关闭逃逸分析: -server -XX:-DoEsca ...

  4. java虚拟机的逃逸分析

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

  5. 面试问我 Java 逃逸分析,瞬间被秒杀了。。

    记得几年前有一次栈长去面试,问到了这么一个问题: Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在考什么知识点,难道对象不是在堆中分配 ...

  6. [转]Java 逃逸分析

    作者:栈长  公众号:Java技术栈 记得几年前有一次栈长去面试,问到了这么一个问题:Java中的对象都是在堆中分配吗?说明为什么! 当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤,当时我压根就不知道他在 ...

  7. 逃逸分析(Escape Analysis)

    一.什么是逃逸 逃逸是指在某个方法之内创建的对象,除了在方法体之内被引用之外,还在方法体之外被其它变量引用到:这样带来的后果是在该方法执行完毕之后,该方法中创建的对象将无法被GC回收,由于其被其它变量 ...

  8. JVM中启用逃逸分析

    -XX:+DoEscapeAnalysis 逃逸分析优化JVM原理我们知道java对象是在堆里分配的,在调用栈中,只保存了对象的指针.当对象不再使用后,需要依靠GC来遍历引用树并回收内存,如果对象数量 ...

  9. JVM笔记-逃逸分析

    参考: http://www.iteye.com/topic/473355http://blog.sina.com.cn/s/blog_4b6047bc01000avq.html 什么是逃逸分析(Es ...

随机推荐

  1. 20145312 《Java程序设计》第八周学习总结

    20145312 <Java程序设计>第八周学习总结 学习笔记 Chapter 15时间与日期 15.1 日志 15.1.1 日志API简介 java.util.logging包提供了日志 ...

  2. 20145322 《Java程序设计》第7周学习总结

    20145322何志威 <Java程序设计>第7周学习总结 教材学习内容总结 第十二章 如果使用JDK8的话,可以使用Lambda特性去除重复的信息. 在只有Lambda表达式的情况下,参 ...

  3. arm-linux工具

    arm-linux工具的功能如下: arm-linux-addr2line 把程序地址转换为文件名和行号.在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上 ...

  4. java自带的MD5

    前言:        MD5可生成16.32.64位数的签名. // MD5加码,32位 public static String toMD5(String plainText) { String r ...

  5. RabbitMQ 的路由模式 Topic模式

    模型 生产者 package cn.wh; import java.io.IOException; import java.util.concurrent.TimeoutException; impo ...

  6. sass快速入门 - 笔记

    一.使用变量 1.使用$符号来标识变量. 例: $nav-color:#F90; .nav{ $width:100px; width:$width; color:$nav-color; }

  7. mysql数据库优化课程---15、mysql优化步骤

    mysql数据库优化课程---15.mysql优化步骤 一.总结 一句话总结:索引优化最立竿见影 1.mysql中最常用最立竿见影的优化是什么? 索引优化 索引优化,不然有多少行要扫描多少次,1亿行大 ...

  8. Python 的selenium使用

    一.Radio 判断radio是否已经被选中 driver.find_element_by_id().is_selected() 其返回值为bool类型,True or False 二.frame f ...

  9. HDU1595-最短路-删边

    find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  10. 使用curl调试openstack的api

    一 系统环境 OpenStack: Mitaka 工具: 最简单的工具:restclient,本次使用curl 二 开搞 访问openstack的API之前,用户使用用户名和密码向keystone进行 ...