DEV Community

Cover image for Java Memory Management Explained
naveen kumar
naveen kumar

Posted on

Java Memory Management Explained

Heap vs Stack vs Metaspace — With Real Code & Real Scenarios

If you're learning Java for backend development, cracking interviews, or building scalable systems — understanding JVM memory is non-negotiable.

Most developers write code.
Professional developers understand how memory behaves underneath.

Let’s break it down clearly

What is Java Memory Management?

Java Memory Management is the process by which the JVM (Java Virtual Machine):

Allocates memory

Manages memory

Cleans unused memory using Garbage Collection (GC)

Unlike C/C++, Java automatically manages memory — making it safer and more scalable.

But automatic does NOT mean “no problems”.

If you misunderstand memory:

APIs slow down

Apps crash

Production fails

Interviews become difficult

JVM Memory Structure Overview

The JVM divides memory into different runtime areas:

Heap Memory

Stack Memory

Metaspace

(Internally: PC Register & Native Method Stack)

Let’s focus on the big three.

Heap Memory — Where Objects Live

What is Heap?

Heap memory is the runtime area where:

Objects are stored

Instance variables are stored

Arrays are stored

Heap is shared across all threads.

Whenever you use new, memory is allocated in the heap.

`class Student {
   String name;
}

public class Main {
   public static void main(String[] args) {
       Student s1 = new Student();
       s1.name = "Swathi";
   }
}`
Enter fullscreen mode Exit fullscreen mode

What happens internally?

new Student() → Object created in Heap

s1 → Reference stored in Stack

"Swathi" → Stored in String Constant Pool (Heap area)

Heap Structure

Heap is divided into:

🔹 Young Generation

Newly created objects

Frequently cleaned by GC

🔹 Old Generation

Long-living objects

Cleaned less often

Before Java 8, we had PermGen.
Now replaced with Metaspace.

❌ Common Heap Error
java.lang.OutOfMemoryError: Java heap space

Causes:

Infinite object creation

Large collections

Memory leaks

Poor GC tuning

Stack Memory — Where Methods Execute

What is Stack?

Stack memory stores:

Method calls

Local variables

Function parameters

Primitive data types

Each thread has its own stack.

Stack follows LIFO (Last In, First Out).

💻 Example

`public class Main {

   public static void display() {
       int x = 10;
       System.out.println(x);
   }

   public static void main(String[] args) {
       display();
   }
}``
Enter fullscreen mode Exit fullscreen mode

Execution Flow:

`main() pushed into stack

display() pushed

x stored in stack

display() removed

main() removed`
Enter fullscreen mode Exit fullscreen mode

Stack cleans itself automatically when methods finish.

❌ StackOverflowError Example

`public class Test {
public static void recursive() {
recursive();
}

public static void main(String[] args) {
recursive();
}
}
`
This causes:

java.lang.StackOverflowError

Because recursion keeps filling stack frames until memory runs out.

Metaspace — Where Class Metadata Lives

What is Metaspace?

Metaspace stores:

Class metadata

Method metadata

Static variables

Constant pool data

Before Java 8 → PermGen
After Java 8 → Metaspace

Why Metaspace Was Introduced?

PermGen had fixed size and caused:

java.lang.OutOfMemoryError: PermGen space

Metaspace:

Uses native memory

Grows automatically

More flexible

💻** Example**

class Demo {
   static int count = 0;
}

Enter fullscreen mode Exit fullscreen mode

Class structure → Metaspace

Static variable → Metaspace

How Garbage Collection Works

Garbage Collection removes unused objects from heap.

Modern GC Algorithms:

Serial GC

Parallel GC

G1 GC

ZGC (low-latency modern GC)

💻 GC Example

public class GCExample {
   public static void main(String[] args) {
       String s1 = new String("Java");
       s1 = null;
       System.gc();
   }
}
Enter fullscreen mode Exit fullscreen mode

Once reference becomes null, object becomes eligible for GC.

⚠ System.gc() is only a suggestion — JVM decides.

Memory Leak in Java (Yes, It’s Possible)

Even with GC, memory leaks can happen.

import java.util.ArrayList;

public class LeakExample {
   static ArrayList<String> list = new ArrayList<>();

   public static void main(String[] args) {
       while (true) {
           list.add("Memory Leak");
       }
   }
}
Enter fullscreen mode Exit fullscreen mode

Here:

Objects keep getting added

Never removed

Heap fills up

OutOfMemoryError occurs

GC cannot remove objects that are still referenced.

String Pool in Java

String constant pool is inside heap.

String s1 = "Java";
String s2 = "Java";

Both refer to same object.

But:

String s3 = new String("Java");

Creates a new object.

String pooling improves memory efficiency.

🛠 Tools to Monitor JVM Memory

Professional engineers use:

JVisualVM

JConsole

Eclipse MAT

JVM monitoring tools

Used to analyze:

Heap usage

GC activity

Memory leaks

Thread dumps

Real Production Scenario

In large enterprise applications:

Improper heap usage slows APIs

Deep recursion crashes services

Static misuse retains memory

Poor GC tuning increases latency

Understanding memory is directly connected to backend performance.

Final Thoughts

Java Memory Management is not just theory.

It is:

A core backend skill

A critical interview topic

A production performance factor

A DevOps optimization area

If you master:

Heap

Stack

Metaspace

Garbage Collection

You move from “Java coder” → to “JVM-aware backend engineer”.

🔎 FAQs
What is Heap memory?

Stores objects and instance variables.

What is Stack memory?

Stores method calls and local variables per thread.

What is Metaspace?

Stores class metadata and static variables.

What causes StackOverflowError?

Deep or infinite recursion.

What causes OutOfMemoryError?

Heap memory full and GC cannot free space.

Where are static variables stored?

In Metaspace (Method Area).

Top comments (0)