Where does the JVM store primitive variables?

Solution 1:

Simplistic answer: it depends on where the variable is declared, not on its type.

Local variables are stored on the stack. Instance and static variables are stored on the heap.

Don't forget that for reference type variables, the value of a variable is a reference, not the object. (Arrays are reference types too - so if you have an int[], the values will be on the heap.)

Now, this is potentially an overly simplistic answer, because a smart VM may be able to detect if a particular reference type variable refers to an object which can never "escape" the current method. If that's the case, it could potentially inline the whole object on the stack.

But conceptually this model is accurate. So a variable of type int which is declared as an instance variable like this:

class Foo
{
    private int value;
    ...
}

will conceptually live on the heap, as part of the data of any instance of Foo. It will be freed as part of freeing the instance - it's just 4 bytes within the block of data representing a Foo instance; it doesn't need separate deallocation.

Solution 2:

Where a variable is stored depends on whether a variable is a local variable or an instance variable.

Local variables are stored on the stack. Instance and static variables are stored on the heap.

Let me explain this with an example. Lets say we have an instance variable animal of some custom class Animal. Animal animal = new Dog(); Here animal is just a reference and is located on the stack. The actual object is allocated memory on the heap. This reference animal will point to this object memory allocated on the heap. So if you have 3 reference pointing to the same object.

Animal animal1 = new Dog();
Animal animal2 = new Dog();
Animal animal3 = new Dog();

All three reference will be in stack. When I say reference it is just a pointer pointing to the object on the heap. In terms of memory this reference holds the address(not actually there a bit more abstraction here) of the object on the heap. So 4 bytes on 32 bits and 8 bytes on 64 bits. Only when all the three references are dereferenced i.e they are no longer in scope(or rather no longer pointing to the original object) then only garbage collector is free to deallocate the memory allocated to the object on the heap.

There is a slight variation when we store primitive types or String literals.Unless you explicitly create their object using new() operator they are created and stored in permGen area of Heap. So both references firstString and secondString in

String firstString = "Stack";
String secondString = "Stack";

will point to the same object in the String pool. It would point to different objects when we create them using new().