欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 【18】逃逸分析

【18】逃逸分析

2025/2/24 7:42:39 来源:https://blog.csdn.net/dyf4281/article/details/141534506  浏览:    关键词:【18】逃逸分析

一、逃逸分析

概念:一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针

Java 虚拟机中的逃逸分析针对的是新建对象

即时编译器判断对象是否逃逸的依据:
1.对象是否被存入堆中(静态字段或者堆中对象的实例字段)
2.对象是否被传入未知代码中


public void forEach(ArrayList<Object> list, Consumer<Object> f) {Itr iter = new Itr; // 注意这里是new指令iter.cursor = 0;iter.lastRet = -1;iter.expectedModCount = list.modCount;while (iter.cursor < list.size) {if (list.modCount != iter.expectedModCount)throw new ConcurrentModificationException();int i = iter.cursor;if (i >= list.size)throw new NoSuchElementException();Object[] elementData = list.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();iter.cursor = i + 1;iter.lastRet = i;Object obj = elementData[i];f.accept(obj);}
}

新建的ArrayList$Itr实例既没有被存入任何字段之中,也没有作为任何方法调用的调用者或者参数。因此,逃逸分析将断定该实例不逃逸。

二、基于逃逸分析的优化

即时编译器可以根据逃逸分析的结果进行诸如锁消除、栈上分配以及标量替换的优化。

锁消除

锁对象不逃逸就意味着该锁对象的加、解锁都没有意义。
即时编译器可以消除对该不逃逸锁对象的加锁、解锁操作

synchronized (new Object()) {}会被完全优化掉。这正是因为基于逃逸分析的锁消除。由于其他线程不能获得该锁对象,因此也无法基于该锁对象构造两个线程之间的 happens-before 规则

栈上分配

(1)若不使用逃逸分析技术,对象创建方式:
JVM对象都是在堆上分配的,堆上的内容对任何线程可见,JVM需要对所分配的堆内存进行管理。

需要借助垃圾回收器来处理不再被引用的对象。

(2)若使用逃逸分析技术,对象创建方式:

逃逸分析证明新建对象不可逃逸之后:
若证明某些新建的对象不逃逸,JVM可以将其分配至栈上,并且在 new 语句所在的方法退出时,通过弹出当前方法的栈桢来自动回收所分配的内存空间。

无须借助垃圾回收器来处理不再被引用的对象。

标量替换

标量:仅能存储一个值的变量,比如 Java 代码中的局部变量
聚合量:可能同时存储多个值,其中一个典型的例子便是 Java 对象

标量替换这项优化技术,可以看成将原本对对象的字段的访问,替换为一个个局部变量的访问。

对上述代码标量替换后,由于Itr对象没有被实际分配,因此和栈上分配一样,它同样可以减轻垃圾回收的压力。


public void forEach(ArrayList<Object> list, Consumer<Object> f) {// Itr iter = new Itr; // 经过标量替换后该分配无意义,可以被优化掉int cursor = 0;     // 标量替换int lastRet = -1;   // 标量替换int expectedModCount = list.modCount; // 标量替换while (cursor < list.size) {if (list.modCount != expectedModCount)throw new ConcurrentModificationException();int i = cursor;if (i >= list.size)throw new NoSuchElementException();Object[] elementData = list.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;lastRet = i;Object obj = elementData[i];f.accept(obj);}
}

部分逃逸分析

public static void bar(boolean cond) {Object foo = new Object();if (cond) {foo.hashCode();}
}
// 经过部分逃逸分析,优化为:
public static void bar(boolean cond) {if (cond) {Object foo = new Object();foo.hashCode();}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词