Note: Where does the JVM store primitive variables?
Variables exist in the memory, but where?
Getting Into
The location of variables are located depends on where the variable is declared. Local variables are usually stored on the stack, but instance and static variables are stored on the heap. If variables are placed in the static area, they spend the rest of their lifecycle in the area till the termination of JVM.
To note, reference type variables and the value of a variable is a reference, not the object. Arrays are reference types too, in that int[]
does have their value on the heap.
When it comes to the following code, the variable of the type int
is declared as an instance variable that would conceptually live in the heap area.
class Foo {
private int value;
...
}
Take the following example too.
public class Memory {
public static void main(String[] args) { // Line 1
int i=1; // Line 2
Object obj = new Object(); // Line 3
Memory mem = new Memory(); // Line 4
mem.foo(obj); // Line 5
} // Line 9
private void foo(Object param) { // Line 6
String str = param.toString(); //// Line 7
System.out.println(str);
} // Line 8
}
The graphic below depicts the two memory in relation to the code above and how they are used to hold Primitive, Object and reference variables.
When executing the applications, JRE loads all of the runtime classes into the heap area. That is the first stage. When the main()
the method which is located on line 1 is called, JRE allocates stack memory dedicated to the main()
method to utilize.
Take line 2 which creates a primitive local variable i
which is then saved on the stack memory for the main method. We then constructed an Object
in line 3 with a new
constructor which is to be generated in heap memory. The reference to the object is stored in the stack memory for the main method. Lastly but not least, take line 4 which also creates an another Memory
object, which goes through a similar procedure as line 3 had taken.
When calling the foo
function in the fifth line, a new block is generated at the top of the stack for the foo
method. Since Java has adopted the pass-by-value principle, the passed Object
reference is formed in the foo
stack block in the sixth line.
In the seventh line, a new String is created, which is to be placed in the String pool in the heap space. The reference to the String is created in the foo
stack space. In the last line, the foo
method is finished then the memory block allocated for the foo
method in the stack memory becomes free.
The difference between Stack and Heap Memory
Heap memory is utilized by all components of the application, whereas stack memory is only used by one execution thread. When an object is created, it is always kept in the Heap space, and the reference to it is saved in stack memory. Stack memory only stores local basic variables and references to heap-space objects.
Objects in the heap are globally accessible, whereas stack memory is inaccessible to other threads. Memory management in stack memory is done in a LIFO fashion, but memory management in heap memory is more difficult because it is utilized worldwide.
Heap memory is classified as Young Generation, Old Generation that is explained on the Java Garbage Collection, while Stack memory is temporary, but heap memory exists from the beginning to the end of application execution.
To further note, the -Xms and -Xmx
JVM options can be used to specify the startup size and maximum heap memory size. We may specify the stack memory size with -Xss
. When the stack memory is exhausted, the Java runtime throws java.lang.StackOverFlowError
while if heap memory is full, it throws java.lang.OutOfMemoryError: Java Heap Space
.
Stack memory is far less in size than Heap memory. Stack memory is more faster than heap memory because of the ease of memory allocation (LIFO).