Garbage Collection in Java Explained with Real Examples | JVM Memory Management

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
Note: Garbage Collection works only on Heap Memory. Stack Memory is automatically cleaned when methods complete.

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.

Important: Eligible for Garbage Collection does not mean the object is removed immediately. The JVM decides when to execute Garbage Collection.

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();
Important: These methods only send a request to the JVM. The JVM may ignore the request depending on memory usage and its internal optimization strategy.

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 StringBuilder instead 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

  1. What is Garbage Collection in Java?
  2. Why is Garbage Collection needed?
  3. What is the difference between Heap and Stack Memory?
  4. When does an object become eligible for Garbage Collection?
  5. Can System.gc() guarantee Garbage Collection?
  6. Explain the Mark and Sweep Algorithm.
  7. What are Young Generation and Old Generation?
  8. What is the difference between Serial GC and Parallel GC?
  9. Why is G1 GC the default Garbage Collector in modern Java versions?
  10. What are Stop-the-World pauses?
  11. Can Java applications still have memory leaks?
  12. 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.