逃逸分析(Escape Analysis)与栈上分配
逃逸分析了解JVM内存模型的大都知道Java的对象、数组都是在堆上分配的,实际上JVM还有更高级非分配技术。逃逸分析(Escape Analysis)就是其中之一。逃逸分析是目前Java虚拟机中比较前言的优化技术,他与类型继承关系分析一样,并不是直接优化代码的手段,而是为前天优化手段提供依据的分析技术。逃逸分析的基本行为就是分析动向的动态作用域:当一个对象在方法中被定义后,它可能被外部方法所...
逃逸分析
了解JVM内存模型的大都知道Java的对象、数组都是在堆上分配的,实际上JVM还有更高级非分配技术。逃逸分析(Escape Analysis)就是其中之一。
逃逸分析是目前Java虚拟机中比较前言的优化技术,他与类型继承关系分析一样,并不是直接优化代码的手段,而是为前天优化手段提供依据的分析技术。
逃逸分析的基本行为就是分析动向的动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如,作为调用参数传递到其他方法中。成为方法逃逸。甚至还有可能被外部线程访问到,例如赋值给类变量或者可以在其他线程中访问的实例变量,成为现场逃逸。
public class EscapeTest {
public static Object globalObj;
// 给全局变量赋值,发生逃逸
public void globalVariableEscape() {
globalObj= new Object();
}
// 方法返回值,发生逃逸
public Object methodEscape() {
return new Object();
}
// 实例引用发生逃逸
public void instanceEscape() {
test(this);
}
}
栈上分配
栈上分配主要是指在Java程序的执行过程中,在方法体中声明的变量以及创建的对象,将直接从该线程所使用的栈中分配空间。 一般而言,创建对象都是从堆中来分配的,这里是指在栈上来分配空间给新创建的对象。
如何启用
在JDK 6之后支持对象的栈上分析和逃逸分析,在JDK 7中完全支持栈上分配对象。 其是否打开逃逸分析依赖于以下JVM的设置:
-XX:+DoEscapeAnalysis
实际效果
jvm的参数 -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC
public class AllocationOnStack {
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
for (int index = 0; index < 100000000; index++) {
allocate();
}
long end = System.currentTimeMillis();
System.out.println((end - start)+ " ms");
Thread.sleep(1000*1000);
}
private static void allocate() {
byte[] bytes = new byte[2];
bytes[0] = 1;
bytes[1] = 1;
}
}
控制台输出
[GC (Allocation Failure) 2048K->1043K(9728K), 0.0011874 secs]
[GC (Allocation Failure) 3091K->1474K(9728K), 0.0010678 secs]
[GC (Allocation Failure) 3522K->1530K(9728K), 0.0008986 secs]
[GC (Allocation Failure) 3578K->1546K(9728K), 0.0007104 secs]
8 ms
C:\Users\Lenovo>jstat -gc 1516
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 504.0 0.0 2048.0 1482.5 7168.0 1042.3 4864.0 3259.6 512.0 350.1 4 0.004 0 0.000 0.004
当我们使用参数 -Xmx10m -Xms10m -XX:-DoEscapeAnalysis -XX:+PrintGC
效果
[GC (Allocation Failure) 3850K->1802K(9728K), 0.0002024 secs]
[GC (Allocation Failure) 3850K->1802K(9728K), 0.0001878 secs]
[GC (Allocation Failure) 3850K->1802K(9728K), 0.0001940 secs]
[GC (Allocation Failure) 6572K->4524K(9728K), 0.0002761 secs]
[GC (Allocation Failure) 6572K->4524K(9728K), 0.0002979 secs]
[GC (Allocation Failure) 6572K->4524K(9728K), 0.0002188 secs]
782 ms
C:\Users\Lenovo>jstat -gc 19176
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
512.0 512.0 0.0 0.0 2048.0 1802.0 7168.0 4562.9 4864.0 3781.7 512.0 411.4 1160 0.350 0 0.000 0.350
结论
在测试程序中,逃逸分析往往能获得不错的成绩,但是在实际应用中,尤其是大型程序中反而发现实施逃逸分析可能出现效果不稳定的情况。 如有需要,可以开启该参数,然后对比实际结果。 开始了-XX:+DoExcapeAnalysis后可以添加参数-XX:PrintEscapeAnalysis开查看分析结果。 有了逃逸分析技术支持后,用户可以使用参数-XX:+EliminateAllocations开开启标量替换,使用 -XX:+EliminateLocks开启同步消除,使用-XX:+PrintEliminateAllocations查看标量替换情况。
更多推荐
所有评论(0)