Garbage Collection in Java Explained with Real Examples | JVM Memory Management
Garbage Collection in Java Explained with Real Examples
One of the biggest advantages of Java is that developers don't need to manually manage memory. Unlike programming languages such as C and C++, Java automatically allocates and releases memory using a feature called Garbage Collection (GC).
Whenever an object is no longer used by your application, the Java Virtual Machine (JVM) identifies it and removes it from memory. This automatic memory management reduces memory leaks, improves application stability, and allows developers to focus more on business logic instead of memory allocation.
In this tutorial, you'll learn what Garbage Collection is, why it is important, how it works, different types of garbage collectors, and several real-world examples frequently asked in Java interviews.
What is Garbage Collection?
Garbage Collection is an automatic memory management process performed by the Java Virtual Machine (JVM). It continuously monitors the Heap Memory, identifies objects that are no longer referenced by the application, removes them, and makes that memory available for new objects.
In simple words, Garbage Collection performs four major tasks:
- Find unused objects.
- Delete those objects from Heap Memory.
- Recover the occupied memory.
- Reuse the memory for new objects.
Think of it like this: Imagine your room is full of old books, broken toys, and empty boxes. Cleaning the room regularly creates space for new things. Garbage Collection does the same for your application's memory.
Why is Garbage Collection Needed?
Every Java application creates thousands or even millions of objects during execution. Consider an online shopping application where users browse products, place orders, make payments, and log out.
Each action creates temporary objects such as:
- User objects
- Product objects
- Cart objects
- Order objects
- Payment objects
Once a request is completed, many of these objects become unnecessary. If they remain in memory forever, the application will eventually run out of memory and may throw an OutOfMemoryError.
Garbage Collection automatically removes these unused objects, ensuring the application continues to run efficiently.
Benefits of Garbage Collection
- Automatic memory management
- Reduces memory leaks
- Improves application stability
- No need to manually free memory
- Better developer productivity
- Safer and more reliable applications
Java Memory Structure
To understand Garbage Collection, you first need to understand how Java manages memory. JVM mainly divides memory into two important sections.
1. Stack Memory
Stack Memory stores method calls, local variables, and primitive data types. Every thread has its own stack, and memory is automatically released when a method finishes execution.
Stack stores:
- Method calls
- Local variables
- Primitive values
- Reference variables
2. Heap Memory
Heap Memory is used to store all objects and arrays created using the
new keyword. Since objects may live longer than method execution,
Heap Memory is managed by the Garbage Collector.
Heap stores:
- Objects
- Arrays
- Class instances
- Instance variables
Heap vs Stack Memory
| Stack Memory | Heap Memory |
|---|---|
| Stores local variables | Stores objects and arrays |
| Thread-specific | Shared among all threads |
| Memory released automatically after method execution | Memory released by Garbage Collector |
| Very fast access | Relatively slower |
| Smaller memory size | Larger memory area |
Object Lifecycle in Java
Every object created in Java passes through a simple lifecycle before it is removed from memory.
Create Object
│
▼
Object is Used
│
▼
Reference Removed
│
▼
Eligible for Garbage Collection
│
▼
Memory Reclaimed by JVM
An object becomes eligible for Garbage Collection only when there are no active references pointing to it.
Example
Employee emp = new Employee();
emp = null;
Here, the Employee object has no reference after assigning
null. Therefore, it becomes eligible for Garbage Collection.
The JVM may remove it during the next GC cycle.
How Garbage Collection Works
The JVM continuously monitors Heap Memory. When memory usage increases or Heap becomes full, it starts the Garbage Collection process.
The process generally follows these steps:
Step 1 → Find all reachable objects
↓
Step 2 → Identify unreachable objects
↓
Step 3 → Remove unused objects
↓
Step 4 → Reclaim Heap Memory
↓
Step 5 → Reuse memory for new objects
Since this entire process is handled by the JVM, developers don't need to manually release memory, making Java one of the safest programming languages for enterprise applications.
Real Example 1: Object Becomes Eligible for Garbage Collection
When an object no longer has any reference pointing to it, it becomes eligible for Garbage Collection.
class Employee {
String name = "John";
}
public class Test {
public static void main(String[] args) {
Employee emp = new Employee();
emp = null;
System.gc();
}
}
In this example, the Employee object becomes unreachable after assigning
null to emp. Calling System.gc() only requests
the JVM to perform Garbage Collection. It does not guarantee immediate execution.
Real Example 2: Multiple References
An object is not eligible for Garbage Collection as long as at least one reference still points to it.
Employee emp1 = new Employee();
Employee emp2 = emp1;
emp1 = null;
Here, the object is still referenced by emp2, so it remains in memory.
Real Example 3: Anonymous Object
new Employee();
Since no variable stores the reference, the object becomes eligible for Garbage Collection immediately after creation.
Real Example 4: Reassigning an Object
Employee emp = new Employee();
emp = new Employee();
The first object loses its reference when a new object is assigned to the same variable. Therefore, the first object becomes eligible for Garbage Collection.
Can We Force Garbage Collection?
Java provides two methods that request the JVM to perform Garbage Collection.
System.gc();
or
Runtime.getRuntime().gc();
How Does Garbage Collection Work Internally?
The JVM follows a series of steps to determine which objects should remain in memory.
Application Running
│
▼
Create Objects
│
▼
Check Reachable Objects
│
▼
Mark Unused Objects
│
▼
Delete Unused Objects
│
▼
Free Heap Memory
This process happens automatically in the background and helps maintain healthy memory usage throughout the application's lifecycle.
Mark and Sweep Algorithm
One of the most commonly used Garbage Collection techniques is the Mark and Sweep Algorithm.
Step 1 - Mark Phase
The JVM starts from root references and marks every object that is still reachable.
Object A ✔
Object B ✔
Object C ✘
Object D ✘
Objects A and B are still in use, while Objects C and D have become unreachable.
Step 2 - Sweep Phase
All unmarked objects are removed from Heap Memory, and the released memory becomes available for creating new objects.
Generational Garbage Collection
Instead of scanning the entire Heap every time, Java divides memory into different generations to improve performance.
Heap Memory
│
├── Young Generation
│ ├── Eden Space
│ ├── Survivor 0
│ └── Survivor 1
│
└── Old Generation
Young Generation
Newly created objects are stored here. Most temporary objects die quickly, so this area is cleaned frequently.
Old Generation
Objects that survive multiple garbage collection cycles are promoted to the Old Generation because they are expected to live longer.
Types of Garbage Collectors in Java
1. Serial Garbage Collector
The Serial Garbage Collector uses a single thread to perform all Garbage Collection tasks. It is suitable for small desktop applications with limited memory.
-XX:+UseSerialGC
Advantages
- Simple implementation
- Low memory overhead
- Suitable for small applications
2. Parallel Garbage Collector
Also called the Throughput Collector, it uses multiple threads to perform Garbage Collection faster on multi-core processors.
-XX:+UseParallelGC
Best for:
- Large applications
- High throughput systems
- Batch processing
3. G1 (Garbage First) Collector
G1 GC became the default Garbage Collector from Java 9 onwards. It divides the Heap into multiple regions and collects garbage from the regions containing the most unused memory first.
-XX:+UseG1GC
Benefits
- Low pause time
- Better performance for large Heap sizes
- Suitable for enterprise applications
4. Z Garbage Collector (ZGC)
ZGC is designed for applications requiring extremely low latency. It supports very large Heap sizes while keeping pause times below a few milliseconds.
Ideal for:
- Financial systems
- Real-time applications
- Cloud services
5. Shenandoah Garbage Collector
Shenandoah is another low-pause Garbage Collector that performs most of its work concurrently with the running application, reducing stop-the-world pauses.
Suitable for:
- Large enterprise applications
- Applications with strict response-time requirements
Which Garbage Collector Should You Use?
| Garbage Collector | Best For |
|---|---|
| Serial GC | Small desktop applications |
| Parallel GC | Maximum throughput |
| G1 GC | General-purpose enterprise applications |
| ZGC | Very large heaps with low latency |
| Shenandoah | Applications requiring minimal pause times |
Advantages of Garbage Collection
Garbage Collection is one of the major reasons Java is considered a reliable programming language for enterprise applications. It automatically manages memory, allowing developers to focus on writing business logic instead of handling memory allocation.
- Automatic memory management.
- Reduces the chances of memory leaks.
- Prevents manual memory allocation and deallocation.
- Improves application stability.
- Reduces the risk of application crashes caused by invalid memory access.
- Makes Java development faster and more productive.
Disadvantages of Garbage Collection
Although Garbage Collection simplifies memory management, it also has a few limitations that developers should be aware of.
- Developers cannot control exactly when Garbage Collection will run.
- GC consumes CPU resources while cleaning memory.
- Applications may experience short "Stop-the-World" pauses.
- Creating too many unnecessary objects can affect performance.
Best Practices for Better Memory Management
Even though Java handles memory automatically, following good coding practices can significantly improve application performance.
- Remove object references when they are no longer needed.
- Avoid creating unnecessary temporary objects.
- Reuse objects whenever possible.
- Use
StringBuilderinstead of repeated String concatenation inside loops. - Close files, database connections, and streams using
try-with-resources. - Use appropriate data structures for your use case.
- Monitor memory usage using tools like VisualVM or Java Mission Control.
Common Myths About Garbage Collection
Myth 1: Java Never Has Memory Leaks
Reality: Java applications can still experience memory leaks if objects are unintentionally kept referenced for a long time.
Myth 2: System.gc() Immediately Cleans Memory
Reality: System.gc() only requests Garbage Collection. The JVM decides whether or
not
to execute it.
Myth 3: Objects Are Deleted Instantly
Reality: An object is only removed when it becomes unreachable and the JVM decides to run Garbage Collection.
Frequently Asked Questions (FAQ)
Does Garbage Collection work on Stack Memory?
No. Garbage Collection works only on Heap Memory. Stack Memory is automatically released when a method finishes execution.
Can Garbage Collection remove active objects?
No. Objects that are still referenced by the application are never removed.
Can developers manually delete objects?
No. Java does not provide a delete keyword like C++. Memory management is handled automatically by the JVM.
Is Garbage Collection automatic?
Yes. The JVM automatically decides when Garbage Collection should run based on memory usage.
Which memory area is cleaned by Garbage Collection?
Only Heap Memory is managed by the Garbage Collector.
Java Garbage Collection Interview Questions
- What is Garbage Collection in Java?
- Why is Garbage Collection needed?
- What is the difference between Heap and Stack Memory?
- When does an object become eligible for Garbage Collection?
- Can
System.gc()guarantee Garbage Collection? - Explain the Mark and Sweep Algorithm.
- What are Young Generation and Old Generation?
- What is the difference between Serial GC and Parallel GC?
- Why is G1 GC the default Garbage Collector in modern Java versions?
- What are Stop-the-World pauses?
- Can Java applications still have memory leaks?
- How do you optimize memory usage in Java applications?
Key Takeaways
- Garbage Collection automatically removes unused objects from Heap Memory.
- Developers do not need to manually free memory in Java.
- Objects become eligible for Garbage Collection only when no references point to them.
System.gc()is only a request, not a guarantee.- Modern Java applications commonly use the G1 Garbage Collector.
- Writing efficient code helps the Garbage Collector perform better.
Conclusion
Garbage Collection is one of Java's most valuable features because it automates memory management and helps applications run efficiently. By identifying and removing unused objects from Heap Memory, the JVM reduces the risk of memory leaks and allows developers to concentrate on building robust applications instead of managing memory manually.
Understanding concepts such as object eligibility, Heap vs Stack Memory, the Mark and Sweep algorithm, and different Garbage Collectors like Serial GC, Parallel GC, G1 GC, ZGC, and Shenandoah is essential for every Java developer. These topics are not only important for writing high-performance applications but are also frequently asked in Java interviews.
We hope this guide helped you understand Garbage Collection in Java with real examples. Continue exploring JVM internals and memory optimization techniques to become a more confident and efficient Java developer.