You are currently viewing Garbage Collector in Java: Everything You Need to Know

Garbage Collector in Java: Everything You Need to Know

Introduction

Memory management is a critical aspect of software engineering, and Java distinguishes itself by handling much of this complexity automatically. The Java Garbage Collector (GC) is an integral component of the Java Virtual Machine (JVM) that reclaims memory occupied by unused objects, allowing developers to focus more on program logic than on manual memory allocation. This article provides a comprehensive guide to the workings of the Java Garbage Collector, highlighting its strategies, mechanisms, and practical implications for developers.

1. What is Garbage Collection in Java?

Garbage collection in Java refers to the automated process by which the JVM identifies and frees memory that is no longer in use by the application. Whenever an object is created, memory is allocated from the heap. If there are no more references to the object, it becomes eligible for garbage collection.

“Garbage collection is Java’s promise to developers: ‘You create objects; I’ll clean them up when you’re done.'”

This automated process dramatically reduces memory leaks and segmentation faults, problems often encountered in languages that require manual memory management.

For an overview of Java memory locations, read our article on Memory Locations in Java.

2. How Does the Java Garbage Collector Work?

The Java Garbage Collector operates in the background, using algorithms to periodically scan memory and remove objects that are no longer reachable. The primary method of identifying unreachable objects is the concept of reachability: if an object cannot be reached by any live thread, it is considered garbage.

Generational Garbage Collection

The heap is typically divided into several sections:

  • Young Generation: Where new objects are allocated. Short-lived objects are quickly collected here.
  • Old (Tenured) Generation: Where long-lived objects are eventually promoted.
  • Permanent Generation / Metaspace: Holds metadata, such as class definitions (since Java 8, Metaspace replaced PermGen).

This division allows the collector to optimize performance, as most objects die young and can be reclaimed quickly.

“Most Java objects are like shooting stars—they shine briefly and vanish, making generational collection very efficient.”

3. Types of Java Garbage Collectors and How to Select One

Java offers multiple garbage collector (GC) implementations, each optimized for specific use cases and workload patterns. Choosing the right garbage collector can dramatically affect application performance, responsiveness, and memory footprint. Therefore, understanding their strengths and the selection process is essential.

The main Java garbage collector types are:

  • Serial GC:
    Uses a single thread for garbage collection. It is best suited for small applications or single-threaded environments where pause times are not critical.
  • Parallel GC (Throughput Collector):
    Employs multiple threads to manage heap space. It’s designed for multiprocessor systems and applications where high throughput is more important than pause times.
  • Concurrent Mark Sweep (CMS) GC:
    Performs most GC work concurrently with application threads, minimizing pause times. It is ideal for applications that require low latency but is now deprecated in recent Java versions in favor of G1.
  • G1 Garbage Collector:
    Splits the heap into regions and balances between high throughput and low pause times. G1 is the default garbage collector in modern Java versions (from Java 9 onward). It is suitable for both desktop and server applications.
  • ZGC and Shenandoah:
    These are modern, low-latency collectors designed for applications with large heap sizes and strict pause time requirements. Both collectors aim for pause times of less than 10 milliseconds.

“Choosing the right garbage collector is like selecting the engine for your car—it determines both performance and efficiency.”

How to Select a Java Garbage Collector

To select a garbage collector, you can use JVM command-line options when starting your Java application. The most common options are:

  • Serial GC:
    -XX:+UseSerialGC
  • Parallel GC (default in Java 8):
    -XX:+UseParallelGC
  • G1 GC (default from Java 9):
    -XX:+UseG1GC
  • ZGC:
    -XX:+UseZGC (requires Java 11+)
  • Shenandoah:
    -XX:+UseShenandoahGC (requires Java 12+ and an OpenJDK build with Shenandoah)

Example:

java -XX:+UseG1GC -Xmx2G -jar yourapp.jar

Selection Criteria:

  • Application Size and Latency Sensitivity:
    For small or CLI applications, Serial GC is often enough.
    For web or server apps, G1 or Parallel GC may be preferable.
    For low-latency, large-heap apps, consider ZGC or Shenandoah.
  • Pause Time Goals:
    Use G1, ZGC, or Shenandoah if predictable short pauses are essential.
  • JVM Version:
    Availability of collectors depends on your Java version.

Tip:
You can profile your application using built-in tools like JVisualVM or GC logs to measure performance under different collectors.

“Tune your garbage collector as you would tune your database: monitor, measure, and iterate for best results.”

4. How to Make Objects Eligible for Garbage Collection

Objects become eligible for garbage collection when there are no more active references pointing to them. This situation can occur in several ways:

  • Nullifying references: Setting an object’s reference to null removes its only path of reachability.
  • Reassigning references: Assigning a new object to an existing reference.
  • Objects going out of scope: Local variables within a method are no longer referenced after the method completes.
  • Islands of Isolation: Two or more objects reference each other but are unreachable from any live thread.

Example: Making Objects Eligible for GC

The following code demonstrates how objects can become unreachable:

// This method shows various ways objects become eligible for garbage collection
public void eligibilityDemo() {
    String temp = new String("Temporary"); // 'temp' points to a String object
    temp = null; // Now the String object is eligible for GC

    Object a = new Object();
    Object b = a;
    a = null; // 'b' still points to the object, so it is not eligible yet
    b = null; // Now the Object is unreachable
}

Description:
In this example, the first String object becomes eligible for GC after its reference is set to null. In the second case, both a and b need to be nullified before the object is collectible.

5. Forcing Garbage Collection: Myths and Practices

Although Java provides the System.gc() method to suggest garbage collection, it is only a request, not a command. The JVM is free to ignore this request.

// Suggests that the JVM performs garbage collection (no guarantee)
System.gc();

Description:
Calling System.gc() signals the JVM, but there is no guarantee that garbage collection will actually occur at that moment.

“You can ask Java to take out the trash, but you can’t make it do it now.”

Instead of forcing GC, developers should write memory-efficient code, minimizing unnecessary object creation and managing references wisely.

6. Monitoring and Tuning the Garbage Collector

Java provides several tools and techniques to monitor and tune garbage collection behavior:

  • JVM Options: Flags like -Xms, -Xmx, and collector-specific flags.
  • JVisualVM and JConsole: GUI tools for visualizing GC activity and memory usage.
  • Garbage Collection Logs: Enable detailed GC logs with JVM parameters.

Monitoring GC helps detect memory leaks and optimize application performance. For further exploration of Java memory, check out Memory Locations in Java.

7. Code Demonstration: Garbage Collection in Action

The code below demonstrates garbage collection eligibility and includes comments about memory management:

package com.kloudly;

// Demonstrates how Java garbage collector works and when objects become eligible for GC
public class GarbageCollectorDemo {

    public static void main(String[] args) {
        GarbageCollectorDemo demo = new GarbageCollectorDemo();
        demo.eligibilityDemo();

        // Suggests garbage collection (but does not guarantee)
        System.gc();
        System.out.println("System.gc() called.");
    }

    // Shows various ways objects become eligible for garbage collection
    public void eligibilityDemo() {
        String local = new String("I will be collected"); // Heap object
        local = null; // Eligible for GC

        ExampleObject obj1 = new ExampleObject();
        ExampleObject obj2 = obj1;
        obj1 = null; // obj2 still points to the object
        obj2 = null; // Now the ExampleObject is unreachable

        ExampleObject isolatedA = new ExampleObject();
        ExampleObject isolatedB = new ExampleObject();
        isolatedA.partner = isolatedB;
        isolatedB.partner = isolatedA;
        isolatedA = null;
        isolatedB = null; // Both objects reference each other but are unreachable (island of isolation)
    }

    // Simple object class for demonstration
    static class ExampleObject {
        ExampleObject partner;
    }
}

Description:
This code illustrates multiple ways that objects become unreachable and thus eligible for garbage collection, including nullifying, reassigning, and forming isolated object groups.

Conclusion

The Java Garbage Collector is an advanced mechanism that helps developers manage memory safely and efficiently. By understanding how it works and knowing best practices for object lifecycle management, Java programmers can write more reliable and performant applications. In summary, the garbage collector is your silent partner in preventing memory leaks and keeping your Java applications robust.

For more memory management articles, see Memory Locations in Java and Understanding the Stack and Heap in Java.

“Trust in the garbage collector, but design your code as if you are the collector.”

You can find the complete code of this article on GitHub.

Noel Kamphoa

Experienced software engineer with expertise in Telecom, Payroll, and Banking. Now Senior Software Engineer at Societe Generale Paris.