Skip to main content

7.1 Garbage Collection Fundamentals & Generational Hypothesis

← Back to Chapter 7: Garbage Collection & Serialization

Garbage Collection is the process of automatically finding unused objects in Heap memory and removing them to free memory.


What is Garbage Collection?​

In Java, we create objects using new.

User user = new User();

This object is stored in Heap memory.

When we no longer need the object, ideally its memory should be released.

In languages like C/C++, developers often manually release memory. Java does this automatically using Garbage Collection (GC).

What exactly is "Garbage"?​

An object that is no longer reachable from the application is called Garbage.

Example:

User user = new User();

user = null;

Initially:

user ───────> User Object

After user = null:

user ──X──> User Object

User Object
↓
Garbage

The object is now eligible for GC.

Important:

Eligible for GC does NOT mean immediately deleted.

The JVM decides when GC should actually run.

Why do we need Garbage Collection?​

Without GC Heap memory keeps filling with unused objects. After GC the unused object are removed and memory is released.

Stack vs Heap​

Stack contains :​

local variables method calls references to objects

Heap contains :​

actual objects

Stack:
user reference disappears

Heap:
User object may become unreachable
↓
Eligible for GC

How does Java know an object is unused?​

Java mainly uses reachability.

If the objects are not reachable by the GC root objects, they are considered as Garbage.

What are GC Roots?​

GC Roots are objects/references from which Java starts checking whether other objects are reachable.

Common GC Roots include:

1. Local variables in active threads
2. Static variables
3. Active Java threads
4. JNI references
5. Some JVM internal references

Does System.gc() perform Garbage Collection?​

It is a request/suggestion to the JVM to perform GC.

It does not guarantee that GC will happen immediately.

System.gc();
Runtime.getRuntime().gc();

Another way of requesting GC

Can we force Garbage Collection?​

No. You can request it using System.gc().

JVM decides whether and when to perform GC.

How does Garbage Collection actually work?​

Application creates objects
↓
Heap fills
↓
GC triggered
↓
Find reachable objects
↓
Identify unreachable objects
↓
Remove/reclaim them
↓
Memory reused

Generational Garbage Collection​

  1. Most objects die shortly after instantiation (e.g. local loop variables, temporary DTOs, HTTP request contexts).
  2. References from older objects to younger objects are extraordinarily rare.

Heap Division​

┌───────────────────────────────────────────┬───────────────────────────────────────────┐
│ Young Generation │ Old Generation │
│ │ (Tenured) │
│ ┌──────────────────────┬─────────┬──────┐ │ ┌───────────────────────────────────────┐ │
│ │ Eden Space │ S0 │ S1 │ │ │ Long-lived survived objects │ │
│ │ (Fresh allocations) │ Survivor│ │ │ │ (Promoted after threshold, e.g. 15) │ │
│ └──────────────────────┴─────────┴──────┘ │ └───────────────────────────────────────┘ │
└───────────────────────────────────────────┴───────────────────────────────────────────┘

Young Generation​

Young Generation contains newly created objects.

Old Generation​

Old Generation contains objects that have survived for a relatively long time.​

GC Phases (Steps of GC)​

  1. Mark: JVM finds objects that are still reachable. It marks the objects that are alive.
  2. Sweep: JVM removes unreachable objects and frees there memory.
  3. Compact: After removing garbage, there may be empty gaps. Compaction moves objects together. This makes future allocation easier.

Stop-The-World (STW)​

During some GC phases, application threads may need to stop. This is known as Stop-The-World.

Why is Stop-The-World a problem?​

But GC pauses application threads causes:

API latency ↑
timeouts
slow application