0

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?

Community
  • 1
  • 1
Sipko
  • 880
  • 7
  • 9
  • `test` is an *Object*.. Furthermore, when you see `new` keyword, this should be a hint that the heap is involved.. – Maroun Sep 15 '13 at 12:54
  • My apologies, I confused the terms "Object" and "variable". I edited it. – Sipko Sep 15 '13 at 12:59
  • @Maroun Maroun From this post: http://stackoverflow.com/questions/18810505/declaring-multiple-arrays-with-64-elements-1000-faster-then-declaring-array-of/18810801?noredirect=1#18810801 , I understand objects can be placed on a stack that is not part of the heap, correct me if I misunderstood please. – Sipko Sep 15 '13 at 13:01
  • While objects that do not escape the method technically could be allocated on the stack, they are not. From [here:](http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis) "After escape analysis, the server compiler eliminates scalar replaceable object allocations and associated locks from generated code. The server compiler also eliminates locks for all non-globally escaping objects. It does *not* replace a heap allocation with a stack allocation for non-globally escaping objects." – kiheru Sep 15 '13 at 13:13
  • Please fix the code. There is something wrong in the first few lines. However, I do not see a performance difference when testing the fixed code on my machine. – nosid Sep 15 '13 at 14:02
  • @nosid Sorry I accidently double pasted and only removed part of the full copy. Fixed it now. – Sipko Sep 15 '13 at 14:35
  • @nosid you don't see any performance difference when you leave the "test[0] = 10" out or not? Thank you for looking into this question as well btw. – Sipko Sep 15 '13 at 14:38

2 Answers2

0

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

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
  • But if test would be on the stack the garbage collector would not be called right? Also it does not explain why it takes longer if I alter one of the elements inside the object. – Sipko Sep 15 '13 at 13:15
0

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'

alhugone
  • 66
  • 2