打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java逃逸分析

  1. java逃逸是什么东西?

  2. 我怎么知道是否开启了逃逸分析?

  3. 为什么对象可以不在堆上分配内存?

  4. 代码示例


1.java逃逸是什么东西?
可以理解为jvm为了减少GC和优化内存使用做出的一种优化方案,由JIT动态编译器进行优化,所以通过反编译是看不出来的

2.我怎么知道是否开启了逃逸分析?
逃逸分析的JVM参数是 DoEscapeAnalysis,通过java -client -XX: PrintFlagsInitial 打印一下JVM参数默认值(我这里是1.8版本)


可以发现默认是开启了逃逸分析。

3.为什么对象可以不在堆上分配内存?
JVM逃逸做了如下几种对代码的优化,锁消除,标量替换等手段,将对象所需空间在栈中分配,减少gc回收,锁消除的JVM参数是EliminateLocks ,标量替换是EliminateAllocations,还是通过上面方法去搜索,发现默认是开启的(1.8版本)



4.代码示例
首先是锁消除,对象在方法内创建,并且在方法内加锁,这样是没有意义的,每一次调用方法都会new新的对象,并对新的对象加锁

private void sync() {        Object o = new Object();        synchronized(o) {            System.out.println(o);        }    }

jit动态编译代码优化为

private  void sync(){        Object o = new Object();        System.out.println(o);    }

在方法内部创建一个没有被外部引用的对象,就会不会发生逃逸,但是如果像下图这种,方法内部的对象被拿到外部使用了那么就发生了逃逸

private StringBuilder sync(String a,String b){        StringBuilder sb = new StringBuilder();        sb.append(a);        sb.append(b);        return sb;    }

如果对象仅仅在方法内部使用,不将引用传递出去,是不会发生逃逸的,比如改成这样

private String sync(String a,String b){        StringBuilder sb = new StringBuilder();        sb.append(a);        sb.append(b);        return sb.toString();    }

这样StringBuilder 的引用就消失了,会顺利的被回收掉,下面是标量替换,对象在方法内创建,无外部引用,会被标量所替换,减少GC和堆上内存使用

private void sync() {   Sync sync= new Sync(1,2);   System.out.println("x" sync.x  "y"  sync.y);}class Sync{        public Sync(int x, int y) {            this.x = x;            this.y = y;        }        private int x;        private int y;    }

替换结果

private void sync(){        int x = 1;        int y = 2;        System.out.println("x" sync.x  "y"  sync.y);    }

参考博客

JIT百度百科

来源:https://www.icode9.com/content-1-418951.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
性能: 字符串拼接
Java之String重点解析
痴情研究java内存中的对象
【总结】String in Java
String
面试问我 Java 逃逸分析,瞬间被秒杀了。。
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服