27

Where does the Java JVM store primitive variables, and how is the memory used by primitives freed after use?

I guess it is on the stack?

mtk
  • 13,221
  • 16
  • 72
  • 112
JRomio
  • 2,407
  • 3
  • 26
  • 27

3 Answers3

46

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Isn't java treats primitive & non-primitive variable's differently? – JRomio Sep 13 '10 at 06:10
  • Also array contents are in the heap. I would say "local variables except for captured variables" but I just read your article on the different between Java and C# closures and I guess there's no such thing as a captured *variable* in Java. In C# it would be on for stack for local variables, unless captured, and members of value types which are on the stack, and on the heap for array contents and members of reference types. – Ben Voigt Sep 13 '10 at 06:10
  • @Ben: Yes, will add that about arrays, although it's already covered, strictly speaking, as arrays are reference types. In C# you'd *also* need to cover local variables in iterator blocks, which will be on the heap too. – Jon Skeet Sep 13 '10 at 06:12
  • 1
    @JRomio: All local variables are either a built-in type or a handle (which Java calls a reference, but it's really a pointer at heart) to a user-defined type, both of which are primitive. Only the pointed-to UDT is non-primitive, but that's distinct from the variable holding the handle. – Ben Voigt Sep 13 '10 at 06:12
  • While array elements are definitely content within a reference type, calling an array element an "instance or static variable" is a bit of a stretch, no? – Ben Voigt Sep 13 '10 at 06:14
  • 2
    @Ben: In that case I wouldn't call it a variable at all. I didn't state that *everything* in the heap is an instance or static variable. Anyway, it's definitely better after clarification, so thanks :) @Rakesh: Yes, arrays are reference types. Did you think the entire contents of the array was copied every time you performed an assignment? – Jon Skeet Sep 13 '10 at 06:31
  • Also java does cache some ints. In that case would the int in Foo point to that cache and never gets deallocated? Or would those cached objects be used only for stack local instances? – Sid Jan 14 '16 at 14:59
  • @Sid: Do you mean `Integer`? The idea of an `int` being cached is meaningless... it's just the 4 byte value... it isn't an object. – Jon Skeet Jan 14 '16 at 21:17
9

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().

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • A small mistake when talking about `Dog` objects. There are three different objects pointed to by three different `Animal` references. – asgs Jun 12 '17 at 19:23
6
  • Class objects, including method code and static fields: heap.
  • Objects, including instance fields: heap.
  • Local variables and calls to methods: stack..
kleopatra
  • 51,061
  • 28
  • 99
  • 211
siddu
  • 61
  • 1
  • 1