Java Heap Space vs. Stack Memory: How Java Applications Allocate Memory

By: angelas
  |  March 18, 2023
Java Heap Space vs. Stack Memory: How Java Applications Allocate Memory

Java applications need a certain amount of RAM on a computer to run. Each time an object or variable is declared, it needs more RAM. Simply designating enough memory to hold every value declared and run each method would lead to a bloated application.

To keep application memory requirements lean, it is partitioned in ways that require less memory and allows the application to run more quickly.

The Java Virtual Machine (JVM) divides memory between Java Heap Space and Java Stack Memory in a way that only uses memory that’s needed.

What is Java Heap Space

It is created by the Java Virtual Machine when it starts. The memory is used as long as the application is running. Java runtime uses it to allocate memory to objects and Java Runtime Environment (JRE) classes.

When an object is created, it is always created in Heap and has global access. That means all objects can be referenced from anywhere in the application.

It is managed by two concepts: Garbage collection and young-generation, old-generation.

Garbage collection works to free memory by clearing any by objects without any references in the methods. These are objects that are no longer being used. Clearing them ensures they don’t take up space in the Heap.

Young-generation, old-generation helps prioritize objects for garbage collection by dividing Java Heap Space into two generations.

The nursery is the younger generation where the new objects are stored. When the nursery is full, garbage collection cleans it out. Note only the memory space for the nursery is full. There is still memory in the old generation.

The old generation is home to objects have been around long enough. When the old generation runs out of room, garbage collection removes the objects not being used in the old space. Again, only part of the Heap is full when old garbage collection happens. There is still room in the nursery.

What is Java Stack Memory?

This is the temporary memory where variable values are stored when their methods are invoked. After the method is finished, the memory containing those values is cleared to make room for new methods.

When a new method is invoked, a new block of memory will be created in the Stack. This new block will store the temporary values invoked by the method and references to objects stored in the Heap that are being used by the method.

Any values in this block are only accessible by the current method and will not exist once it ends.

When the method ends, that block will be erased. The next method invoked will use that empty block.

This “last in, first out” method makes it easy to find the values needed and allows fast access to those values.

How They’re Used in a Java Application

Let’s look at a very simple example of a Java application to see how memory is allocated.

package com.journaldev.test;package com.journaldev.test;
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
}

In the above example from JournalDev.com, the use of Stack and Heap is explained as follows:

  • All Runtime classes are loaded into the Heap Space when the program is run.
  • Java Runtime creates Stack memory to be used by main() method thread when it is found at line 1. At line 2, a primitive local variable is created, which is stored in the Stack memory of main() method.
  • Since an Object is created at line 3, it’s created in Heap memory and the reference for it is stored in Stack memory. At line 4, a similar process occurs when a Memory object is created.
  • When foo() method is called at line 5, a block in the top of the Stack is created for it. Since Java is pass by value, a new reference to Object is created in the foo() stack block in line 6.
  • At line 7, a string is created, which goes in the String Pool in the Heap space, while a reference for it is created in the foo() stack space. At line 8, foo() method is terminated, and the memory block allocated for it in the Stack is freed.
  • Finally, at line 9, main() method terminates, and the Stack memory created for it is destroyed. Because the program ends at this line, Java Runtime frees all the memory and ends the execution of the program.

Key Differences

  • Java Heap Space is used throughout the application, but Stack is only used for the method — or methods — currently running.
  • The Heap Space contains all objects are created, but Stack contains any reference to those objects.
  • Objects stored in the Heap can be accessed throughout the application. Primitive local variables are only accessed the Stack Memory blocks that contain their methods.
  • Memory allocation in the Heap Space is accessed through a complex, young-generation, old-generation system. Stack is accessed through a last-in, first-out (LIFO) memory allocation system.
  • Heap Space exists as long as the application runs and is larger than Stack, which is temporary, but faster.

Additional Resources and Tutorials

To learn more, check out the following resources:

Stack and heap are two ways Java allocates memory. Understanding when and how they work is critical for developing better Java programs.

It’s also helpful to understand how allocation works when dealing with memory leaks. Additional tools for Java for you to explore include Prefix to write better Java code for free and the full lifecycle APM, Retrace.

Improve Your Code with Retrace APM

Stackify's APM tools are used by thousands of .NET, Java, PHP, Node.js, Python, & Ruby developers all over the world.
Explore Retrace's product features to learn more.

Learn More

Want to contribute to the Stackify blog?

If you would like to be a guest contributor to the Stackify blog please reach out to [email protected]