Marco Pace
Marco Pace

Reputation: 3870

Java heap & stack

I want to study Java again, because I leave it some years ago. Reading a book I had a problem understanding how Java allocate memory in heap and in stack.

This is what I've understood - I'll try to speak about it with examples.

class TestA {
    int a;

    void methodA(int b) {
        a = b;
    }

    int getA() {
        return a;
    }
}

This is a sample class to show different situation. And this is my main:

int b = 3;

TestA obj = new TestA();
obj.methodA(b);
obj.getA();

So what happen?


## BEGIN

STACK - take some memory for main function

HEAP - empty


## int b = 3

STACK - [take some memory for main function -> here we have b]

HEAP - [empty]


## TestA obj = new TestA()

STACK - [take some memory for main function -> here we have b and a reference to TestA]

HEAP - [take some memory for int a]


## obj.methodA(b);

STACK - [take some memory for main function -> here we have b and a reference to TestA]

HEAP - [take some memory for int a] AND [another memory for methodA]


## execute methodA(int b)

STACK - [take some memory for main function -> here we have b and a reference to TestA] AND [take memory for methodA() -> here we have b used in this function]

HEAP - [take some memory for int a] AND [another memory for methodA]


We have:

Is it right?

Upvotes: 2

Views: 2148

Answers (3)

ekj
ekj

Reputation: 1082

By default all objects are allocated on the heap. However, there are compiler optimization that allow objects to be allocated on the stack (or avoid allocation all together). In particular escape analysis allows this in java 6.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075367

At the outset, remember that the heap will also have the Class instance for your class (and several others).

Re:

## TestA obj = new TestA()

STACK - [take some memory for main function -> here we have b and a reference to TestA]

HEAP - [take some memory for int a]

a will be in the heap, not on the stack, as part of the memory allocated for the instance of TestA. b and obj are on the stack, allocated upon entry to main (er, I think that's when that happens; it could be that the JVM doesn't reserve stack space for them until it encounters the declarations in the program flow, but there we're getting into internals of the JVM). The heap also contains the instance of TestA. (Remember that obj, the variable, is quite distinct from what it points to [the instance of TestA]; each of those things takes memory.)

Also remember that the stack will contain the return addresses for the function calls. E.g., when main calls methodA, the address that the JVM should come back to when methodA returns is also on the stack.

Various stack structures will also be allocated for exception handling.

The above is mostly theoretical, mind. JVMs are welcome to do optimizations, and they do (HotSpot is a thoroughly optimizing JVM). @Voo points out, for instance, that JVMs may well put objects on the stack if they detect that they can (for instance, when the object instance is only used within the method and bytecode analysis by the JVM shows that it's impossible for there to be an outstanding reference to it when the method exits).

Upvotes: 2

Mike Samuel
Mike Samuel

Reputation: 120576

Although Java is specified as a stack machine, it is not actually implemented that way in practice, so in real JVMs the size of the stack only changes on exit or entry to a method.

The heap is never empty -- it includes objects like Object.class among others which are instantiated by a bootstrap classloader before main starts.

All actions like new ClassName(...) allocate space in the heap* and all variable declarations (int x, Object ref) specify that space should be set aside on the stack when the enclosing function is entered**.

* - see caveat regarding optimizations at https://stackoverflow.com/a/8690592/20394
** - again optimizations can cause stack slots to be shared.

Upvotes: 1

Related Questions