🧹
Memory & Lifecycle

Memory Management & Garbage Collection

How Java Cleans Up
💡 The Heap is a big warehouse where all the objects live. The Stack is a small to-do list that tracks method calls. The Garbage Collector is a cleaner who walks through the warehouse and removes objects nobody is using anymore.

Stack memory stores method calls and local variables — fast, and automatically cleaned up once the method ends.

Heap memory stores objects (created with "new") — they stick around as long as some reference is using them.

The Garbage Collector (GC) automatically finds and removes objects with no remaining references — you never need to manually free memory in Java.

void createObjects() {
  Student s = new Student(); // heap par banta hai
} // method khatam -> s ab unreachable -> GC eligible
🧹
The Heap is a big warehouse where all the objects live. The Stack is a small to-do list that tracks method calls. The Garbage Collector is a cleaner who walks through the warehouse and removes objects nobody is using anymore.
1 / 6
⚡ Quick Recap
  • Stack = method calls, fast, auto-cleaned
  • Heap = objects, this is where GC works
  • GC = automatic memory cleanup
On this page (5 subtopics)

Stack memory stores method calls and local variables — fast (it's just a pointer moving for push/pop), and it cleans up automatically the moment a method finishes (no GC needed). Every thread has its own separate Stack.

Heap memory stores objects (created with "new") — these stick around for a long time, until nothing references them anymore. The Heap is shared across all threads (which is why access to heap objects needs to be synchronized in multithreading).

StackHeap
StoresMethod calls, local variables, referencesObjects, instance fields
SpeedVery fastA bit slower
SizeSmall, fixed (can get StackOverflowError)Large, configurable (-Xmx flag)
Thread-specific?Yes, each thread has its ownNo, shared across all threads
CleanupAutomatic (when a method returns)Garbage Collector

The JVM splits the Heap into generations because experience shows — "most objects die young" (most objects become unused pretty quickly, like a temporary object created inside a loop). The Young Generation is for new objects — GC runs here very often, and it's fast (since it's scanning a small area).

Objects that survive a long time (surviving multiple GC cycles) get promoted to the Old Generation (Tenured) — GC runs less often here, and it's a bit slower (a bigger area, but it runs rarely).

Serial GC: single-threaded, for small applications/single-core machines — simple but pause times can be large.

Parallel GC: uses multiple threads for GC, throughput-focused (finishing the total work fast, not too worried about pause times).

G1 (Garbage First): the modern default (Java 9+), splits the Heap into small regions and gives predictable, small pause times — best for large applications, especially where response time matters.

Even with automatic GC, memory leaks can still happen: (1) adding objects to a static collection without ever removing them (like a static List that never gets emptied) — static references stay "reachable" for the JVM's entire lifetime.

(2) unclosed resources (files, database connections) that GC doesn't clean up (GC only manages memory, not external resources) — this is exactly why try-with-resources matters. (3) listeners/callbacks that are registered but never unregistered — in all these cases the objects stay "reachable", so GC can't remove them, even though they're practically "unused".

⚠️Common Mistake: "Java doesn't have memory leaks" is a myth — GC only cleans up UNREACHABLE objects. If any reference is left behind (even accidentally, like inside a static collection), that object can stay in memory forever.

Older Java had a finalize() method that ran before an object was garbage collected, for cleanup — but it was unpredictable (no idea when it would run, might never run, GC was in control), so it was deprecated in Java 9+ and is being prepared for complete removal in Java 18.

Modern approach: use the AutoCloseable interface + try-with-resources, which gives deterministic (guaranteed, immediate, predictable) cleanup — this is the right way to do things like closing files/connections.