1. The Hook (The "Byte-Sized" Intro)
- In a Nutshell: Garbage Collection (GC) = automatic memory cleanup.
- Process: (1) Mark reachable objects (from GC roots), (2) Sweep unreachable objects, (3) Compact (optional, defragment).
- GC Roots: Local vars, static vars, active threads, JNI refsβstarting points for reachability.
- Generational hypothesis: Most objects die young β Young Gen GC (frequent, fast), Old Gen GC (rare, slow). Minor GC = Young Gen only, Major/Full GC = whole heap.
- Key: Reachable from root = alive, unreachable = garbage!
Think of city cleaning. GC Roots = city hall, hospitals (essential buildings). Reachable objects = houses connected by roads. **
Mark & Sweep** = inspector walks from city hall, marks reachable buildings, demolishes unmarked (garbage). Generational = clean residential area (young) daily, industrial zone (old) monthly!
2. Conceptual Clarity (The "Simple" Tier)
π‘ The Analogy
- GC Roots: Tree roots (starting points)
- Reachable objects: Connected branches
- Unreachable objects: Dead leaves (garbage)
- Mark phase: Tag all living things
- Sweep phase: Remove dead things
GC Process
graph TD
A[GC Roots] --> B[Mark Phase]
B --> C[Sweep Phase]
C --> D[Compact Phase<br/>Optional]
B --> E[Mark reachable<br/>objects]
C --> F[Remove unreachable<br/>objects]
D --> G[Defragment memory]
style A fill:#2E7D32
style E fill:#F57C00
style F fill:#C2185B
style G fill:#1976D2
3. Technical Mastery (The "Deep Dive")
GC Algorithms
| Algorithm | Description | Used In |
|---|---|---|
| Mark-Sweep | Mark live, sweep dead | Old Gen (CMS) |
| Mark-Copy | Copy live to new space | Young Gen |
| Mark-Compact | Mark live, compact | Old Gen (Serial, Parallel) |
4. Interactive & Applied Code
java
public class GarbageCollectionDemo {
public static void main(String[] args) {
demonstrateReachability();
demonstrateGCRoots();
demonstrateGenerationalGC();
}
// Reachability demonstration
static void demonstrateReachability() {
System.out.println("=== REACHABILITY ===");
// Object 1: Reachable (referenced by local var)
Person p1 = new Person("Alice");
// Object 2: Reachable (referenced by p1.friend)
p1.friend = new Person("Bob");
// Object 3: Unreachable (no references)
new Person("Carol"); // β Eligible for GC immediately!
// Make p1 unreachable
p1 = null; // β Alice and Bob now unreachable (garbage)
// Suggest GC (not guaranteed to run immediately)
System.gc();
}
// GC Roots demonstration
static Person staticPerson = new Person("Static"); // GC Root: static var
static void demonstrateGCRoots() {
System.out.println("\n=== GC ROOTS ===");
// GC Root 1: Local variable
Person local = new Person("Local"); // Reachable!
// GC Root 2: Static variable
System.out.println(staticPerson.name); // Reachable via static!
// GC Root 3: Active thread
Thread thread = new Thread(() -> {
Person threadLocal = new Person("Thread"); // Reachable while thread runs
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
});
thread.start();
// After method ends:
// - 'local' no longer reachable β GC candidate
// - 'staticPerson' still reachable (static)
// - 'threadLocal' reachable until thread finishes
}
// Generational GC demonstration
static void demonstrateGenerationalGC() {
System.out.println("\n=== GENERATIONAL GC ===");
// Short-lived objects (die young)
for (int i = 0; i < 1000; i++) {
String temp = "Temp " + i; // β Dies in Eden (Minor GC)
}
// Long-lived objects (survive to Old Gen)
List<Person> longLived = new ArrayList<>();
for (int i = 0; i < 100; i++) {
longLived.add(new Person("Person " + i)); // β
Survives, promoted to Old Gen
}
System.out.println("Created short and long-lived objects");
}
}
class Person {
String name;
Person friend;
Person(String name) {
this.name = name;
}
@Override
protected void finalize() {
// Called before GC (deprecated, don't use!)
System.out.println(name + " is being garbage collected");
}
}
// Young Generation GC simulation
class YoungGenGCDemo {
public static void main(String[] args) {
/*
Young Gen GC Process:
1. New objects allocated in Eden
2. Eden full β Minor GC
3. Live objects copied to S0 (Survivor 0)
4. Age incremented
5. Next GC: S0 β S1, age++
6. After ~15 GCs: Promoted to Old Gen
*/
// Allocate many short-lived objects
for (int i = 0; i < 10000; i++) {
byte[] temp = new byte[1024]; // 1KB
// Immediately unreachable β GC'd in Eden
}
// Long-lived object
byte[] longLived = new byte[1024 * 1024]; // 1MB
// Survives multiple GCs β Promoted to Old Gen
}
}5. The Comparison & Decision Layer
| Minor GC | Major/Full GC |
|---|---|
| Young Generation only | Old Gen or whole heap |
| Frequent (seconds) | Rare (minutes/hours) |
| Fast (milliseconds) | Slow (up to seconds) |
| Stop-The-World (short) | Stop-The-World (long) |
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question: "What are GC Roots?" Answer: Starting points for reachability analysis!
4 types of GC Roots:
- Local variables (on stack)
- Static variables (in Metaspace, values in heap)
- Active threads
- JNI references (native code)
java
class Demo {
static Person staticRoot = new Person("Static"); // GC Root #2
void method() {
Person local = new Person("Local"); // GC Root #1
local.friend = new Person("Friend"); // NOT a root, but reachable via 'local'
}
}
// After method(): 'local' gone β Friend unreachable β GC'd
// 'staticRoot' persists β Always reachablePro-Tips:
- Generational hypothesis:
text
Weak Generational Hypothesis:
- Most objects die young (within first GC)
- Few survive to old age
Result:
- Young Gen GC: Frequent, fast (most garbage)
- Old Gen GC: Rare, slow (little garbage)- Object promotion:
text
Eden β Survivor 0 β Survivor 1 β ... β Old Gen
Age 1 Age 2 Age 15
Promotion criteria:
- Age threshold (default 15)
- Survivor space full
- Large objects (directly to Old Gen)