4

For a statement in a Java function:

Xxx xxx = new Xxx() {
    public Abc abc(final Writer out) {
        return new SomeFunction(out) {
            boolean isDone = false;
            public void start(final String name) {
                /* blah blah blah */
            }
        };
    }
};

Which variable, including the functions, are put on the heap, and which will be put on stack?

The reason I'm asking this is a segmentation fault in the JVM:

kernel: java[14209]: segfault at 00002aab04685ff8 rip 00002aaab308e4d0 rsp 00002aab04685ff0 error 6

00002aab04685ff8 and 00002aab04685ff0 are near, it seems that the stack is growing too fast. I try to investigate this part of code, and doubt whether it is the cause of problem when calling this function for many times. Is it possible that the stack is not cleared if it is referenced by some variables on the heap?

trincot
  • 317,000
  • 35
  • 244
  • 286
Harold Chan
  • 799
  • 3
  • 11
  • 31

2 Answers2

6

The question of whether a particular object goes on the heap is a bit involved.

In general, in Java, all objects are allocated on the heap, because a method may return or store a pointer to the object. If the object had been put on the stack, it would be overridden the next time a stack frame is put there.

However, the HotSpot JIT compiler does something called Escape Analysis. This analysis finds out whether an object "escapes" the scope of the method by looking at the method's code. If an object doesn't escape, the compiler may safely allocate it on the stack.

Wikipedia has some more information about Escape Analysis in Java, also regarding multi-threading and locking.


Regarding the stack overflow: Stack frames on the call stack are always removed after the method finishes. Actually, there is not even a need to explicitly remove it. The next frame will just override what was previously there.

Also, although in other languages (like C) it is possible to cause the stack to overflow by putting very large objects on the stack, I don't think this could happen in Java. I expect the engineers at Sun (Oracle) to be smart enough to not make the VM store huge objects on the stack.

So the only possibility to have a stack overflow is to have too many nested method invocations. Since the stack space is big enough to handle any "normal" method invocation nesting, a stack overflow normally indicates an infinite (or very large) recursion in your code.

rolve
  • 10,083
  • 4
  • 55
  • 75
  • Why would it do that ? I agree, it's faster to retrieve something from a stack than from a heap, but does it really matter in a time when CPUs perform billions of operations per second ? – Radu Murzea May 07 '12 at 12:25
  • 2
    There are many reasons to rather have objects on the stack: First, the stack has a much higher probability to be in the cache, giving you cache locality for the local variables. Second, the less objects you have on the heap, the less busy will your garbage collector be. Third, objects on the stack are guaranteed to be accessed only by a single thread, so there's no need for locking them. – rolve May 07 '12 at 12:26
  • so, you think the code I posted is not the cause of the problem, right? – Harold Chan May 07 '12 at 12:30
  • @rolve Thank you for your answer. This escape analysis does sound interesting, I'll look for more information about it. What worries me is that all the optimization gained from storing objects on the stack is lost by the overhead of doing the analysis in the first place. – Radu Murzea May 07 '12 at 12:35
  • 1
    @Harold: Well, first of all, your should never see a seg fault in Java anyway. This is probably a bug in the JVM. So, no, I don't think that your code is the cause of the problem. Or to formulate it differently: Your code **might** be the cause of the problem, but it's not your fault... – rolve May 07 '12 at 12:37
  • @SoboLAN: I don't think you have to worry too much. First, the escape analysis only has to be done once, for example when a class is loaded. Given that a method is called many times during the program's run, the overhead vanishes pretty quickly. Second, a JIT compiler normally only starts expensive analyses when it sees that a certain piece of code is executed often, meaning it is a "hot spot". Hence the name of the HotSpot compiler. – rolve May 07 '12 at 12:41
  • 2
    @rolve Excellent summary. I would add that compilation is done in a background thread so its impact is relatively small. Unfortunately escape analysis is complex and rarely (in my experience) results in the elimination of even trivial objects in the HotSpot compiler. I have seen varargs arrays removed, but not much else. The JRockit JVM is supposed to be better but I haven't seen this for myself. – Peter Lawrey May 07 '12 at 12:47
  • 3
    e.g. try `for (Integer i = 0; i < Integer.MAX_VALUE; i++);` with `-verbosegc` ;) – Peter Lawrey May 07 '12 at 12:49
  • @PeterLawrey Yeah, thanks for the addition and the code. Another good example of a big discrepancy between theory and practice. – rolve May 07 '12 at 13:03
  • @rolve I have asked a couple of the engineers why this is so and the response has been that "its complicated" I had thought of writing a tool which does the optimisation for you, but also decided it was a bit complicated. ;) – Peter Lawrey May 07 '12 at 14:32
0

name, isDone, out, ABC and a "pointer" to the anonymous someFunction will all be on the Stack; the rest goes to heap.

Romain
  • 12,679
  • 3
  • 41
  • 54
  • 2
    Would be cool if there was a bit more prose than just that - the original poster cannot **learn** anything from this answer. – Romain May 07 '12 at 11:52
  • If there is the function is called many times, will stack overflow occur as some of them are referenced by objects in heap? – Harold Chan May 07 '12 at 11:53
  • @Harold this is a completely different question. stack overflow is due to the objects on the stack only. [You can read this.](http://stackoverflow.com/questions/214741/what-is-a-stack-overflow-error) – UmNyobe May 07 '12 at 11:58
  • `name` is a string object. `writer` is also an object. Are you _sure_ they're on the stack? – paxdiablo May 07 '12 at 11:58
  • @UmNyobe, As some of them are put on stack as blackcoffeerider said, will it cause the stackoverflow problem by running the functions many times? – Harold Chan May 07 '12 at 12:02