#存储位置分析
Java中,数据存放位置一般可以在堆、以及栈上。一般局部变量等数据都存放在栈上,而对于堆,大部分人理解所有通过new操作符创建的对象都在堆上,但事实上是这样的吗?
请看如下代码:
public class AllotOnStack {
public static void main(String[] argv){
long start = System.currentTimeMillis();
for (long i=0;i<Long.MAX_VALUE;i++){
alloc();
}
}
private static void alloc(){
User user = new User(); new a object
user.setId(1);
user.setName("Hello");
}
}
class User{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
当运行该程序时,可以对JVM加上以下参数:
-Xmx15m -Xms15m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:+EliminateAllocations
其中,DoEscapeAnalysis 为逃逸分析,加上该参数后,JVM将对程序中的new操作进行分析,如果它只是一个局部变量,没有被外部引用(如alloc()方法中的 User user = new User()),该对象将会被分配在栈上面,随着每一次方法调用结束,该变量会被动被销毁。 从而提升了性能。
EliminateAllocations的作用则是标量分析,即对于某个对象,如果当前栈上没有连续的空间分配给该对象,那么程序可能不去创建该对象,而改为直接创建它的若干个被这方法使用的成员变量代替。
为了对比,可以将JVM的参数改为,便能发现,JVM将产生大量的GC操作。
-Xmx15m -Xms15m -XX:-DoEscapeAnalysis -XX:+PrintGC -XX:-EliminateAllocations
对于DoEscapeAnalysis 以及EliminateAllocations,在JDK1.7以上是默认开启的。