Stack and Heap Memory in Java

Arsh GhaiwatArsh Ghaiwat
4 min read

In Java, memory is managed automatically by the Java Virtual Machine (JVM). But as a developer, understanding how memory is allocated and cleared can help you write better, faster, and more reliable programs.

Two main parts of memory used when a Java program runs are:

  • Stack memory – for method-level work

  • Heap memory – for storing objects

To fully understand these, let’s start with what happens when your code runs.


🧠 Where is Java Code Stored?

When you run a Java program, the compiled .class files are loaded into a special memory area called the Method Area (part of the Metaspace in modern JVMs). This area stores:

  • Class names and metadata

  • Method code (bytecode)

  • Static variables

  • Constant pool (like final strings)

✅ The Method Area is shared by all threads. It holds the structure of your program, not the actual data created at runtime.


📌 What Happens When You Run a Program?

Let’s say you run this:

public class Test {
    public static void main(String[] args) {
        int a = 10;
        Person p = new Person("Alice");
    }
}

Here’s how memory is used:

  1. The main method runs → a new stack frame is created

  2. Variable a is a primitive → stored directly in stack

  3. new Person("Alice") creates a Person object → stored in heap

  4. The reference p to that object → stored in stack


🧱 Stack Memory – Method-Level Data

What is Stored in Stack?

  • Local variables like int, boolean, etc.

  • Method parameters

  • References to heap objects

Each time a method is called, the JVM creates a stack frame for that method. This frame holds:

  • Method parameters

  • Local variables

  • Intermediate values

When the method finishes, the stack frame is popped off, and memory is cleared automatically.

Example:

public class Demo {
    public static void main(String[] args) {
        int x = 5;
        int result = add(x, 3);
        System.out.println(result);
    }

    static int add(int a, int b) {
        int sum = a + b;
        return sum;
    }
}

Stack memory is fast and automatically cleared when methods finish.


🌳 Heap Memory – For Objects

What is Stored in Heap?

  • All objects created using new

  • Instance variables inside objects

  • Arrays

When you create an object using new, the JVM stores it in heap memory. The reference to that object is stored in the stack.

Heap memory is shared across all threads. Objects stay in the heap until they're no longer used, and the JVM's Garbage Collector eventually removes them.

Example:

class Person {
    String name;

    Person(String name) {
        this.name = name;
    }
}

public class Test {
    public static void main(String[] args) {
        Person p = new Person("Alice");
    }
}

🧹 Garbage Collection in Java

Heap memory is not automatically cleared like the stack. Instead, Java uses Garbage Collection (GC) to remove unused objects.

When Does GC Clean Up?

GC looks for unreachable objects—objects with no variable pointing to them.

Person p = new Person("Bob");
p = null;  // Now the object has no reference

The Person object is now unreachable. GC will eventually detect and remove it from the heap.

GC doesn’t run immediately. The JVM decides when to run it based on memory needs.


🔄 Stack and Heap Together – End-to-End Flow

class Car {
    String model;

    Car(String model) {
        this.model = model;
    }
}

public class MemoryDemo {
    public static void main(String[] args) {
        Car c = createCar();
        System.out.println(c.model);
        c = null; // Now the object is unreachable
    }

    static Car createCar() {
        Car obj = new Car("Tesla");
        return obj;
    }
}

Memory Timeline:

  1. main() starts → stack frame created (c lives here)

  2. createCar() is called → stack frame created (obj lives here)

  3. new Car("Tesla") → Car object stored in heap

  4. createCar() returns → its stack frame is removed

  5. c in main() still points to the heap object

  6. After c = null → object becomes eligible for GC


✅ Recap

FeatureStack MemoryHeap Memory
StoresMethod calls, local variablesAll objects and their data
AccessFastSlower
LifetimeUntil method endsUntil no references exist
Shared?No (per thread)Yes (shared among threads)
Cleaned byJVM automatically (on method return)JVM Garbage Collector

🧠 Final Thoughts

  • Use stack memory for temporary, method-specific data

  • Use heap memory for objects that may be used across methods or threads

  • Let the Garbage Collector do the cleanup, but understand when and why objects are removed

0
Subscribe to my newsletter

Read articles from Arsh Ghaiwat directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arsh Ghaiwat
Arsh Ghaiwat

Associate System Engineer | Currently learning Java & building fun side projects | Blogging my dev journey to revise, reflect, and grow 👨‍💻🚀