Introduction
Garbage Collection (GC) in Java is one of its most powerful features, automating memory management and preventing memory leaks. Unlike languages like C or C++, where developers have to manually allocate and deallocate memory, Java handles it efficiently using different garbage collection algorithms.
In this guide, we will explore everything about Java Garbage Collection, from its working mechanism to different GC algorithms, tuning techniques, and best practices. By the end, you’ll be able to optimize your Java applications for better performance and memory management.
What is Garbage Collection in Java?
Garbage Collection in Java is the process of automatically identifying and reclaiming unused memory occupied by objects no longer in use. It is handled by the Java Virtual Machine (JVM), ensuring efficient memory utilization.
Why is Garbage Collection Important?
- Prevents Memory Leaks – Unused objects can cause applications to slow down.
- Improves Performance – Frees up memory, making applications run smoothly.
- Reduces Developer Workload – Java developers don’t need to worry about manual memory management.
How Java Garbage Collection Works
Java stores objects in heap memory, where they remain until they are no longer needed. The garbage collector removes such objects and reclaims memory.
The Mark and Sweep Algorithm
Garbage Collection works in two main phases:
- Mark Phase – JVM identifies which objects are still reachable and which are not.
- Sweep Phase – The unreachable objects are removed, and memory is reclaimed.
Memory Areas in Java Heap
The heap is divided into:
- Young Generation (contains newly created objects)
- Eden Space: Objects first appear here.
- Survivor Spaces (S0, S1): Recently used objects.
- Old Generation (Tenured Space) – Stores long-lived objects.
- Metaspace – Stores class metadata and class-related information.
Types of Java Garbage Collectors
1. Serial Garbage Collector
- Uses a single thread.
- Best for small applications.
- Enable with:
-XX:+UseSerialGC
2. Parallel Garbage Collector (Throughput GC)
- Uses multiple threads to clean memory faster.
- Suitable for applications that require high throughput.
- Enable with:
-XX:+UseParallelGC
3. CMS (Concurrent Mark-Sweep) Garbage Collector
- Runs alongside the application, reducing pause times.
- Great for low-latency applications.
- Enable with:
-XX:+UseConcMarkSweepGC
4. G1 (Garbage First) Garbage Collector
- Breaks heap memory into regions and cleans them efficiently.
- Best for large-scale applications.
- Enable with:
-XX:+UseG1GC
5. Z Garbage Collector (ZGC)
- Super-fast, can handle memory sizes up to 16TB!
- Available from Java 11+
- Enable with:
-XX:+UseZGC
6. Shenandoah Garbage Collector
- Ultra-low pause times, suitable for real-time applications.
- Available in Java 12+
- Enable with:
-XX:+UseShenandoahGC
Optimizing and Tuning Garbage Collection
Choosing the Right Garbage Collector
- For real-time applications: ZGC or Shenandoah GC.
- For general applications: G1 GC.
- For high throughput applications: Parallel GC.
JVM Parameters for GC Optimization
-Xms<size>
– Sets initial heap size.-Xmx<size>
– Sets maximum heap size.-XX:NewRatio=<value>
– Controls Young/Old memory ratio.-XX:MaxGCPauseMillis=<time>
– Limits GC pause time.
Monitoring GC Performance
- Use
jstat
:jstat -gc <pid>
- Use VisualVM, JConsole, or JProfiler for real-time analysis.
Java Garbage Collection in Action (Code Examples)
Example 1: Requesting Garbage Collection
public class GarbageCollectionDemo {
@Override
protected void finalize() throws Throwable {
System.out.println("Garbage collection is happening!");
}
public static void main(String[] args) {
GarbageCollectionDemo obj1 = new GarbageCollectionDemo();
GarbageCollectionDemo obj2 = new GarbageCollectionDemo();
obj1 = null; // Making object eligible for GC
obj2 = null;
System.gc(); // Requesting GC execution
}
}
Example 2: Memory Leak Example
import java.util.ArrayList;
import java.util.List;
public class MemoryLeakDemo {
static List<String> memoryLeak = new ArrayList<>();
public static void main(String[] args) {
while (true) {
memoryLeak.add("Leaking memory...");
}
}
}
💡 Fix: Use WeakReferences instead of strong references where necessary.
Best Practices for Effective Garbage Collection
✅ Avoid Memory Leaks
- Use WeakReferences for cache objects.
- Set unused objects to
null
.
✅ Optimize Object Creation
- Use object pooling for frequently used objects.
- Prefer
StringBuilder
overString
for string manipulation.
✅ Monitor Garbage Collection
- Use JConsole, VisualVM, or JProfiler to analyze GC performance.
Conclusion
Garbage Collection in Java is a powerful feature that automates memory management. By understanding different GC algorithms, tuning parameters, and best practices, you can make your Java applications efficient and scalable.
Whether you are developing small applications or enterprise-level systems, mastering Java Garbage Collection is key to optimizing performance. 🚀
Further Reading
- Java Official Docs: https://docs.oracle.com/javase/
- JVM Performance Guide: https://www.oracle.com/java/technologies/javase/performance.html
🚀 Now go and master Java Garbage Collection like a pro!