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;