Why is the follow array placed on heap instead of stack in Java

277 views Asked by At

I have recently learned objects can be placed on the stack or on the heap and where it is placed is determined by escape analysis. (Declaring multiple arrays with 64 elements 1000 times faster than declaring array of 65 elements)

In the following example I think the object "test" is placed on the heap, making the runtime a lot longer:

public static void main(String args[]) {
    double start = System.nanoTime();
    long job = 100000000;// 100 million
    int total = 0;
    for (long i = 0; i < job; i++) {
        int j = 0;
        double[] test = new double[63];
        test[0] =1;
        total += test[0];
        while (true) {
            if (j == 0)
                break;
            j--;
        }
        test[0] = 10; // this makes a really big difference
    }
    double end = System.nanoTime();
    System.out.println("Total runtime = " + (end - start) / 1000000 + " ms" + " total ="+ total);
}

If either the while loop is removed or the "test[0] = 10;" statement, the object test is placed on the stack (I derived this from the fact that the garbage collector is not called in this case, whereas it is when both are present. Also the runtime is 350 ms instead of 6803 ms).

My question is why the object test is placed on the heap if I change/access the content of the object after the while loop?

2

There are 2 answers

1
Juned Ahsan On

test is a local reference variable to your main method. All local variables are stored on stack. Here is an image to make you understand what goes on heap and what goes on stack:

enter image description here

0
alhugone On

Also the runtime is 350 ms instead of 6803 ms

I think it is not about stack/heap but optimization. I'm not sure how Java JIT optimization exacly works, but similar code in C/C++ after optimization would look like this:

public static void main(String args[]) {
    double start = System.nanoTime();
    long job = 100000000;// 100 million
    int total = 100000000;
    double end = System.nanoTime();
    System.out.println("Total runtime = " + (end - start) / 1000000 + " ms" + " total ="+ total);
}

maybe if you refer to test:

test[0]=10; 

it causes that for-loop can not be 'removed'