逃逸分析
在Java虚拟机的即时编译(JIT)器,逃逸分析判断对象是否逃逸。一般依据如下的来判断:
- 对象是否被存入堆中
- 对象是否传入未知代码当中
对象一旦被存入堆中,其他线程便可以获取到该线程的引用,即时编译器就无法追踪到该对象的所有代码位置。
关于后者,由于java虚拟器的即时编译是以方法为单位的,位于方法中未被内联的方法调用,即时编译器会将它当成未知的代码。无法确认会不会将调用者或者所传入的参数,传入到堆上。
一般情况下:即时编译器的逃逸分析是放在方法内联之后的,以消除这些未知代码。
基于逃逸分析的优化
即时编译器对逃逸分析的结果进行了分析:诸如锁消除,栈上分配,标量替换。
标量替换
标量 就是值一个无法再分隔成更小数据的数据,如java种得原始的数据类型。
聚合亮就是可以分隔的类型叫做聚合量。
在JIT阶段 经过逃逸分析 发现一个对象不会被外界访问到。那么经过JIT优化就会把这个对象拆解成若干个成员变量来存储。
public static void main(String[] args) {
alloc();
}
private static void alloc() {
Person person = new Person("zhangsan","123456");
System.out.println("point.x="+point.x+"; point.y="+point.y);
}
class Person{
private String username;
private String password;
}
经过逃逸分析之后
private static void alloc() {
String username = "zhangsan";
String password = "123456";
System.out.println("point.x="+x+"; point.y="+y);
}
经过逃逸分析之后就不再是聚合量了。
不过,由于实现起来需要更改大量假设了“对象只能堆分配”的代码,因此 HotSpot 虚拟机并没有采用栈上分配,而是使用了标量替换这么一项技术。