Java 对象、堆或堆栈中的基元?
大多数人说对象中的原语存储在堆中,但是,我从以下性能测试中得到了不同的结果:Java 对象、堆或堆栈中的基元?,java,object,heap-memory,primitive,stack-memory,Java,Object,Heap Memory,Primitive,Stack Memory,大多数人说对象中的原语存储在堆中,但是,我从以下性能测试中得到了不同的结果: public class Performance { long sum = 0; public static void main(String[] args) { // TODO Auto-generated method stub long startTime = System.currentTimeMillis(); long pSum = 0; for(int i = 0; i
public class Performance {
long sum = 0;
public static void main(String[] args) {
// TODO Auto-generated method stub
long startTime = System.currentTimeMillis();
long pSum = 0;
for(int i = 0; i < Integer.MAX_VALUE; i++){
pSum += i;
}
long endTime = System.currentTimeMillis();
System.out.println("time of using primitive:" + Long.toString(endTime - startTime));
System.out.println(pSum);
long startTime1 = System.currentTimeMillis();
Long Sum = 0L;
for(int i = 0; i < Integer.MAX_VALUE; i++){
Sum += i;
}
long endTime1 = System.currentTimeMillis();
System.out.println("time of using object:" + Long.toString(endTime1 - startTime1));
System.out.println(Sum);
Performance p = new Performance();
long startTime2 = System.currentTimeMillis();
for(int i = 0; i < Integer.MAX_VALUE; i++){
p.sum += i;
}
long endTime2 = System.currentTimeMillis();
System.out.println("time of using primitive in object:" + Long.toString(endTime2 - startTime2));
System.out.println(p.sum);
}
我们可以发现使用原语和在对象中使用原语的时间几乎相同。所以我很困惑对象中的原语是否存储在堆中。为什么使用原语和在对象中使用原语的时间成本几乎相同 你什么时候走
Long sum;
...
sum += 1;
理论上,JVM每次分配一个新的Long,因为Long是不可变的。现在,一个真正聪明的编译器可以在这里做一些聪明的事情,但这就解释了为什么第二个循环的时间要大得多。它正在分配Integer.MAXINT新的Sum对象。另一个原因是自动装箱很棘手
另外两个循环不需要分配新对象。一个使用原语int,另一个可以增加Performance.sum
,而无需每次分配新的性能。访问堆栈或堆中的原语int的速度应该大致相同,如图所示
您的计时与堆和堆栈的访问速度关系不大,但与在循环中分配大量对象有关
正如其他人所指出的,微基准测试可能会产生误导。google autoboxing、google JIT优化“对象中的原语存储在堆中”是完全正确的:所有对象都在堆中,因此它们的内容也在堆中。小心从微基准测试中得出太多的推论。
Long sum;
...
sum += 1;