Garbage Collection (GC) in Java is an automatic process that identifies and removes unused objects from the heap memory to free space and prevent memory leaks.
Java’s GC eliminates the need for manual memory management (unlike C/C++), making applications safer and more reliable.
GC works only on Heap Memory, not on stack.
An object becomes eligible for GC when no live reference points to it.
Student s = new Student();
s = null; // eligibleStudent s1 = new Student();
Student s2 = new Student();
s1 = s2; // old object of s1 eligiblevoid test() {
Student s = new Student();
} // s goes out of scope → object eligibleTwo objects referencing each other BUT no external references.
A a = new A();
B b = new B();
a.b = b;
b.a = a;
a = null;
b = null;
// Both eligible for GC (mutually reachable but unreachable from program roots)Modern JVM uses multiple generations to optimize GC.
Heap
├── Young Generation
│ ├── Eden
│ ├── Survivor 1
│ └── Survivor 2
└── Old Generation
Where new objects are created.
- Eden: All new objects allocated here
- After Minor GC → surviving objects moved to Survivor 1
- Next GC → moved to Survivor 2
- After several cycles → promoted to Old Generation
Minor GC is frequent and fast.
Contains long-lived objects.
- Full GC is costlier and can cause noticeable pause times.
- Uses Mark-Sweep-Compact algorithm.
- Mark: Traverse object graph and mark reachable objects.
- Sweep: Remove unmarked (dead) objects.
- Compact (optional): Rearrange memory to avoid fragmentation.
Based on the idea: Most objects die young.
So JVM stores objects in generations and applies different GC strategies per generation.
Results: Faster GC and better performance.
In young generation:
- Live objects are copied between survivor spaces
- Dead objects are discarded
- Very fast because copying uses sequential allocation
Certain GC phases pause all running threads.
STW pauses can occur during:
- Minor GC
- Major GC
- Compaction
- Root scanning
- Single-threaded
- Suitable for single-core, small applications
- Used in client machines
Enable using:
-XX:+UseSerialGC
- Multi-threaded GC for young gen
- Highest throughput
- Used in server-class machines
Enable:
-XX:+UseParallelGC
- Low pause collector
- Most work done concurrently with application threads
- Not used in modern Java
Enable:
-XX:+UseConcMarkSweepGC
- Region-based GC
- Low latency
- Predictable pause times
- Divides heap into many small regions (1–32 MB)
Enable:
-XX:+UseG1GC
- Ultra low latency (<10ms pauses)
- Suitable for large heaps (multi-GB to TB)
- Mostly concurrent
Enable:
-XX:+UseZGC
- Red Hat’s low-pause GC
- Similar to ZGC
Enable:
-XX:+UseShenandoahGC
finalize() was used for cleanup before GC.
@Override
protected void finalize() {
System.out.println("Finalize called");
}But it's deprecated due to:
- Unpredictability
- Poor performance
- Dangerous behavior
- try-with-resources
- AutoCloseable
You may request GC but JVM decides whether to run it.
System.gc();
Runtime.getRuntime().gc();The JVM may ignore this call.
Garbage Collector cannot solve logical memory leaks.
static List<String> list = new ArrayList<>();FileInputStream fs = new FileInputStream("a.txt");Java has four types of references:
| Reference Type | Package | Purpose |
|---|---|---|
| Strong | Default | Never collected |
| Weak | java.lang.ref.WeakReference |
Collected aggressively (used in WeakHashMap) |
| Soft | SoftReference |
Collected only when memory is low |
| Phantom | PhantomReference |
Used for post-mortem cleanup |
WeakReference<Student> ref = new WeakReference<>(new Student());Object is collected when no strong reference exists.
Enable GC logging:
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps
1. New object → Eden
2. Minor GC → Survivor 1
3. Next Minor GC → Survivor 2
4. After several cycles → Old Gen
5. Old Gen fills → Full GC
6. Mark → Sweep → Compact
Young (Eden + S1 + S2) and Old Gen.
- Old gen becomes full
- Metadata area needs cleaning
- System.gc() (not recommended)
Higher overhead, fragmentation, complex implementation.
JVM pauses all threads during certain GC phases.
No. JVM may ignore the request.
- Minor → short pause, young gen
- Major → long pause, old gen
Objects unintentionally remain referenced and cannot be garbage collected.
-
GC removes unreachable objects to free heap memory.
-
Works with multiple generations: Young, Survivor, Old.
-
Minor GC: fast; Full GC: slow but performs compaction.
-
Several collectors exist: Serial, Parallel, G1 (default), ZGC, Shenandoah.
-
finalize()is deprecated; useAutoCloseableinstead. -
Memory leaks can still occur if references are unintentionally kept.
-
GC improves performance but must be tuned for large applications.