Garbage Collection in Java
Garbage Collection (GC) in Java is the automatic process of reclaiming memory occupied by objects that are no longer reachable. The Java Virtual Machine (JVM) manages memory dynamically, ensuring that unreferenced objects are removed to prevent memory leaks and optimize performance.
1. How Does Garbage Collection Work?
The Garbage Collector (GC) tracks and removes objects in the heap memory that are no longer used. It follows these steps:
- Mark Phase – Identifies reachable objects (objects still referenced).
- Sweep/Compact Phase – Reclaims memory from unreferenced objects.
- Relocation (Optional) – Moves objects to compact memory and reduce fragmentation.
2. When Does Garbage Collection Happen?
- GC is triggered automatically when the JVM detects low available memory.
- The method
System.gc()
suggests (but does not guarantee) GC execution. - Finalizers (
finalize()
) were used in earlier versions but are now discouraged.
3. Types of Garbage Collectors in Java
Java provides different types of GC implementations, each optimized for different use cases.
1️⃣ Serial Garbage Collector
- Algorithm: Uses a single thread to perform GC.
- Best For: Small applications or single-threaded environments.
- Enable With:
-XX:+UseSerialGC
2️⃣ Parallel Garbage Collector (Throughput GC)
- Algorithm: Uses multiple threads for GC, reducing pause times.
- Best For: Multi-core systems running applications with high throughput.
- Enable With:
-XX:+UseParallelGC
3️⃣ G1 (Garbage First) Garbage Collector
- Algorithm: Divides heap into regions and collects the least-used ones first.
- Best For: Large applications with low-latency requirements.
- Enable With:
-XX:+UseG1GC
4️⃣ Z Garbage Collector (ZGC)
- Algorithm: Performs concurrent garbage collection with very low pause times.
- Best For: Low-latency applications (e.g., financial systems).
- Enable With:
-XX:+UseZGC
4. How the Heap is Managed in Garbage Collection
The JVM divides the heap into generations for efficient garbage collection:
Generation | Purpose |
---|---|
Young Generation | Stores newly created objects. |
Old (Tenured) Generation | Stores long-lived objects that survived multiple GCs. |
Permanent (Metaspace) | Stores class metadata, method details, and static variables. |
Young Generation Breakdown
- Eden Space – Where new objects are created.
- Survivor Spaces (S0, S1) – Where objects that survive GC are stored temporarily.
Object Aging and Promotion
- Most objects die young (collected in Eden).
- Objects that survive multiple cycles are promoted to the Old Generation.
5. How to Tune and Monitor GC
JVM GC Tuning Flags
You can optimize GC behavior using JVM options:
# Use G1 GC
java -XX:+UseG1GC -Xms512m -Xmx2g MyApp
Monitoring GC Activity
- Using jstat (JVM Statistics)
jstat -gc <PID> 1000
Using VisualVM – Provides a GUI-based tool for monitoring heap usage.Using JConsole – A built-in monitoring tool for JVM performance.
6. Best Practices to Reduce GC Overhead
✔ Use Primitive Types – Avoid unnecessary object creation.
✔ Reuse Objects – Use object pools if necessary.
✔ Optimize Data Structures – Choose the right collections (e.g., use ArrayList
instead of LinkedList
where applicable).
✔ Manually Dereference Objects – Set unused large objects to null
to help GC.
✔ Profile Memory Usage – Use tools like Eclipse MAT, VisualVM, and JProfiler to analyze memory leaks.
7. Example: Garbage Collection in Action
Without Garbage Collection Awareness
public class MemoryLeakExample {
public static void main(String[] args) {
List<int[]> list = new ArrayList<>();
while (true) {
list.add(new int[100000]); // Keeps adding large arrays (causes OutOfMemoryError)
}
}
}
Problem: Memory keeps growing because objects are not freed.
With Proper Object Management
public class GCExample {
public static void main(String[] args) {
List<int[]> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new int[100000]);
if (i % 10 == 0) {
list.clear(); // Helps GC reclaim memory
System.gc(); // Suggest GC (not guaranteed)
}
}
}
}
Solution: Manually clearing unused objects allows GC to free memory.
Conclusion
- Garbage Collection is automatic, but understanding its mechanisms helps optimize performance.
- JVM provides multiple GC algorithms, each suited for different applications.
- Proper memory management practices can reduce GC overhead and prevent memory leaks.
- Monitoring and tuning GC behavior helps achieve better performance in large-scale applications.
🚀 A well-tuned GC leads to a more efficient and scalable Java application!