Effective Java中的第5项Joshua Bloch说避免创建对象池,除非对象的权重非常大,但在jdk源代码中我看到Integer类中的IntergerCache,Long和Font类中的LongCache和CharacterCache。
public class autobox {
/**
* @param args
*/
public static void main(String[] args) {
long start=System.nanoTime();
Integer sum=0;
sum=sum+94; //1-- takes most time
long end=System.nanoTime();
System.out.println(end-start);
for(int i=0;i<1000;i++)
sum=sum+i;
end=System.nanoTime();
System.out.println(end-start); //--2
sum=0;
for(int j=5;j<1000;j++)
sum=sum+j;
end=System.nanoTime();
System.out.println(end-start); //--3
}
}
我的机器上的输出(使用Java SE 1.7)
540686
984338
1450849
看起来语句1创建了太多的对象,只是为了创建一个Integer对象!我不明白这背后的原因。虽然文档提到-XX:AutoBoxCacheMax=<size>
但我收到错误Unrecognized VM option 'AutoBoxCacheMax=0'
。
缓存是否只保留创建的对象而不是创建不必要的对象?
答案 0 :(得分:0)
您无法控制所测量的内容。请在how to do a correct micro benchmark in java上查看。
1)在你的代码中你有:
1 long start=System.nanoTime();
2 Integer sum=0;
3 sum=sum+94; //1-- takes most time
4 long end=System.nanoTime();
你假设第3行需要花费很多时间。实际上它是第2行(见下文)。
2)你System.out.println(...)
包含在2.和3.时间测量中。这是一个问题,因为打印到控制台非常昂贵,应该从测量中消除。
为了说明我重新安排了您的代码并采取了完全不同的措施:
long start;
long end;
start=System.nanoTime();
System.out.println("println test");
end = System.nanoTime();
System.out.println("Time 1: " + (end - start));
start=System.nanoTime();
Integer sum=0;
end = System.nanoTime();
System.out.println("Time 2: " + (end - start));
start=System.nanoTime();
sum=sum+94;
end = System.nanoTime();
System.out.println("Time 3: " + (end - start));
start=System.nanoTime();
for(int i=0;i<1000;i++) {
sum=sum+i;
}
end = System.nanoTime();
System.out.println("Time 4: " + (end - start));
sum=0;
start=System.nanoTime();
for(int j=5;j<1000;j++) {
sum=sum+j;
}
end=System.nanoTime();
System.out.println("Time 5: " + (end - start));
输出:
println test
Time 1: 140572
Time 2: 360759
Time 3: 3420
Time 4: 139639
Time 5: 130619
然后,请不要过多地阅读这些数字。这是一个没有popper预热阶段的测试,没有考虑JIT编译等的影响。