浅谈JVM中的逃逸分析(Escape Analysis)

前言

  • 逃逸分析其实并不是新概念,早在1999年就有论文提出了该技术。但在Java中算是新颖而前言的优化技术,从 \color{red}{JDK1.6} 才开始引入该技术,\color{red}{JDK1.7}开始默认开启逃逸分析。
  • 逃逸分析并不是直接优化的技术,而是作为其他优化的依据。通过动态分析对象的作用域,为其它优化手段如栈上分配、标量替换和同步省略等提供依据。

进行逃逸

发生逃逸行为的情况有两种:
1.方法逃逸:当一个对象在方法中定义之后,作为参数传递到其它方法中
2.线程逃逸:如类变量或实例变量,可能被其它线程访问到


优化策略

一、标量替换(分离对象)

  • 标量(Scalar)是指一个无法再分解成更小的数据的数据。Java中的原始数据类型就是标量。相对的,那些还可以分解的数据叫做聚合量(Aggregate),Java中的对象就是聚合量,因为他可以分解成其他聚合量和标量。在JIT阶段,如果逃逸分析发现一个对象不会被外部访问,并且该对象可以被拆散,那么经过优化之后,并不直接生成该对象,而是在栈上创建若干个成员变量。

二、栈上分配

  • 故名思议就是在栈上分配对象,可以大大减少堆内存的占用。一旦不需要创建对象了,那么就不再需要分配堆内存,也无须进行垃圾回收,实际上是标量替换。

  • 示例代码:

public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            createObject();
        }
        long end = System.currentTimeMillis();
        System.out.println( "cost-time " + (end - start) + " ms" );
        try {
            // 睡眠线程留够时间查看对象的创建数量,防止线程停止进行垃圾回收
            Thread.sleep( 100000 );
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }

    private static void createObject() {
        // Jit对编译时会对代码进行 逃逸分析
        Person person = new Person();
    }

    static class Person {
        private String name;
        private int age;
    }
  • 测试方法:
    1.1. 配置JVM参数-Xmx1G -Xms1G(调大堆空间,避免堆内GC的发生,高版本的jdk默认开启逃逸分析)
    1.2. 运行程序,执行jps查看进程id,执行jmap -histo 进程ID,查看到实例对象个数并没有预期的500000个,说明 JIT 进行逃逸分析优化后将一部分对象分配在了栈上。
开启逃逸对象实例个数

开启逃逸分析:cost-time 4 ms

2.1. 配置JVM参数-Xmx1G -Xms1G -XX:-DoEscapeAnalysis(调大堆空间,避免GC,关闭逃逸分析)
2.2. 运行程序,执行jps查看进程id,执行jmap -histo 进程ID,查看到关闭逃逸分析后堆上的实例个数与预期是相同的。

关闭逃逸分析对象实例个数

关闭逃逸分析:cost-time 8 ms

三、同步省略

  • 线程同步本身比较耗,动态编译同步块的时候,JIT 编译器可以借助逃逸分析来判断同步块所使用的锁对象是否只能够被一个线程访问而没有被其他线程访问到。如果同步块所使用的锁对象通过这种分析被证实只能够被一个线程访问,那么 JIT 编译器在编译这个同步块的时候就会取消对这部分代码的同步。这个取消同步的过程就叫同步省略,也叫 锁消除
  • 示例代码:
 public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000000; i++) {
            createObject();
        }
        long end = System.currentTimeMillis();
        System.out.println( "cost-time " + (end - start) + " ms" );
    }

    public static void createObject() {
        // 开启逃逸分析后此处锁会被消除
        synchronized (new Object()) {

        }
    }
  • 测试方法:使用默认开启逃逸分析的高版本jdk运行程序对比虚拟机配置参数-Xmx1G -Xms1G -XX:-DoEscapeAnalysis(关闭逃逸分析,同时调大堆空间,避免堆内GC的发生)运行程序,看耗时。

小结

  • 逃逸分析可以带来一定程度上的性能优化。但是逃逸分析自身也是需要进行一系列复杂的分析的,这其实也是一个相对耗时的过程。

常见问题

  1. 是不是所有的对象和数组都会在堆内存分配空间?
    答:不一定
  2. 加了锁的代码锁就一定会生效吗?
    答:不一定
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265

推荐阅读更多精彩内容