首先要了解java对象内存是一定存在堆上的吗?
在jdk1.7之前,对象的创建都是在堆空间创建的,但在1.7的版本之后,HotSpot中默认开启了逃逸分析,所以对象还可能存在栈上。
1.如何判断是否发生逃逸分析
发生逃逸分析的情况:
也就是该user对象有可能会被外部使用
public User test2(){
User user=new User();
user.setId(1);
user.setName("xiaoming")
return user;
}
没有发生逃逸分析的情况:
该user对象没有被外部使用
public void test1(){
User user=new User();
user.setId(1);
user.setName("xiaoming")
}
这种没有被外部访问,且如果在堆内存上频繁创建,当方法结束,需要被gc,浪费性能,所以1.7的版本之后,默认开启了逃逸分析,对于这样的对象直接在栈上创建。
2.栈空间不足问题
在栈上分配内存的时候:会把聚合量(引用数据类型)替换为标量(java中的基本数据类型),来减少栈空间的开销。
3.总结
逃逸分析+栈上分配+标量替换
4.实战
前提:-Xmx10M -Xms10M
测试代码:
public class escape {
private static void alloc() {
byte[] b = new byte[2];
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i<10000000; i++) {
alloc();
}
long end = System.currentTimeMillis();
System.out.println("时间:"+(end - start));
}
}
情况1:-XX:+DoEscapeAnalysis -XX:+PrintGCDetail
开启逃逸分析
情况2:-XX:-DoEscapeAnalysis -XX:+PrintGCDetail
关闭逃逸分析
选项“-XX:+PrintEscapeAnalysis”表示查看逃逸分析的筛选结果
开启逃逸分析速度更快!