参考地址:《JVM的逃逸分析》
一个对象(或变量)在方法中处理完毕返回时,返回结果可能会被其他对象引用,或者全局引用,这种现象即为逃逸。或者可以说,一个对象指针被多个线程或方法引用时,该对象指针就是逃逸状态。
public StringBuilder escapeDemo1(String a, String b) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(a);
stringBuilder.append(b);
return stringBuilder;
}
上述代码中,StringBuilder 在方法中是局部的,但返回时可能会有多个线程或方法引用 StringBuilder,这时就构成了逃逸。如果要改为非逃逸情况,则应该返回 String,最后 return stringBuilder.toString()
。
方法栈上对象的调用,正常情况下应该是栈向 Java 堆中查找对象的引用,然后从堆中加载该对象到栈中,直到方法结束。 逃逸分析的优化:不会将对象放到 Java 堆中,而是直接放到了栈中,此时该对象在栈中属于局部变量,不会发生逃逸。而且随着方法执行完毕,栈内存被回收,局部变量也回收了,这样也变相的减轻了 GC 的压力。
注:栈上分配与 TLAB 不同。栈上分配是直接在虚拟机栈中分配了内存,TLAB 是在堆中为线程特别开辟的一块小空间,为了给这个线程更高效的分配对象。
由于栈空间一般小,无法存储大容量数据,所以目前的实现都是采用不那么准确,但是时间压力相对较小的算法来完成逃逸分析,可能导致效果不稳定。逃逸分析的效果只能在满足高频和高数量的小容量的变量分配结构,才是合适的。