Java 缓存在自动装箱中的作用
有效Java中的第5项Joshua Bloch说,除非对象非常重,否则不要创建对象池,但在jdk源代码中,我在Integer类中看到了IntergerCache,在Long和Character类中看到了LongCache和CharacterCacheJava 缓存在自动装箱中的作用,java,autoboxing,Java,Autoboxing,有效Java中的第5项Joshua Bloch说,除非对象非常重,否则不要创建对象池,但在jdk源代码中,我在Integer类中看到了IntergerCache,在Long和Character类中看到了LongCache和CharacterCache public class autobox { /** * @param args */ public static void main(String[] args) {
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
}
}
看起来语句1创建的对象太多了,都是为了只创建一个整数对象!。我不明白这背后的原因。尽管文档中提到-XX:AutoBoxCacheMax=但我得到一个无法识别的错误VM选项“AutoBoxCacheMax=0”。
缓存不应该只保留已创建的对象,而不是创建不必要的对象吗?您无法控制正在测量的对象。请看这一页 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中。三,。时间尺度。这是一个问题,因为打印到控制台非常昂贵,应该从您的测量中删除
为了说明这一点,我重新整理了您的代码并获得了完全不同的度量:
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));
再说一遍,请不要对这些数字读太多。这是一个没有popper预热阶段的测试,没有考虑JIT编译等的影响。为什么要使用包装器类型?整数和=0;这是一种性能很好的方法,这就是为什么Java有基元类型。这只是一个示例程序。不是一个要求。但可能有一个。比如说,如果我必须将其作为值放入HashMap中,我觉得很像。加载Integer类时,每个程序只创建一次缓存。检查缓存是否已经包含对象可能比完全创建整个缓存更昂贵。因为它是一个包装器而不是一个原语,所以它需要做额外的工作来完成相同的任务。现在,对于HashMap的需求,您不能给出原语。因此,您无法在那里进行优化。
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