Skip to content

Garbage Collection

Garbage Collection (GC) in Java is a process by which the Java Virtual Machine (JVM) automatically identifies and removes unused objects from memory, freeing up resources and preventing memory leaks. This process is a key feature of Java’s memory management system, which eliminates the need for manual memory management by the programmer.


Key Features of Garbage Collection

  1. Automatic Memory Management:
    1. Java handles memory allocation and deallocation automatically.
    1. Programmers do not need to explicitly free memory.
  2. Non-Deterministic:
    1. The exact timing of garbage collection is not predictable.
    1. It occurs when the JVM decides it is necessary, such as when memory is low.
  3. Managed Heap Memory:
    1. Objects are created in the heap.
    1. Garbage collection cleans up the heap by removing objects no longer in use.

How Garbage Collection Works

  1. Object Lifecycle:
    1. Objects are created on the heap using new.
    1. Objects become eligible for garbage collection when no active references exist to them.
  2. Eligibility for Garbage Collection:
    1. An object is eligible for garbage collection if it is unreachable.
    1. Unreachable means no live thread can access it.
  3. Reference Counting and Reachability Analysis:
    1. JVM uses a technique called reachability analysis to determine if an object is no longer referenced.
    1. If an object is not reachable from the GC roots, it is considered garbage.

GC Roots

The following references are considered GC roots:

  1. References from active threads.
  2. References from static variables.
  3. References from method-local variables in the stack.
  4. References from JNI (Java Native Interface) handles.

Garbage Collection Process

Mark-and-Sweep Algorithm

  1. Mark Phase:
    1. All reachable objects are marked as alive.
  2. Sweep Phase:
    1. Unmarked objects are considered garbage and are removed.
    1. Memory occupied by these objects is reclaimed.

JVM Garbage Collectors

The JVM offers several garbage collectors optimized for different use cases. Examples include:

  1. Serial GC:
    1. Designed for single-threaded applications.
    1. Uses a simple mark-and-sweep algorithm.
  2. Parallel GC:
    1. Uses multiple threads for garbage collection.
    1. Suitable for multi-threaded applications.
  3. Concurrent Mark-Sweep (CMS) GC:
    1. Minimizes pause times by performing GC concurrently with application threads.
    1. Ideal for applications requiring low latency.
  4. G1 GC (Garbage-First Garbage Collector):
    1. Divides the heap into regions.
    1. Prioritizes collecting regions with the most garbage first.
    1. Suitable for large heaps and applications with low-latency requirements.
  5. ZGC (Z Garbage Collector):
    1. Designed for sub-millisecond pause times.
    1. Works well for very large heaps.

Example of Garbage Collection

Code Example: Object Eligibility for GC

public class GarbageCollectionDemo {

    public static void main(String[] args) {

        // Object 1: Eligible for GC

        String str = new String(“Hello”);

        str = null; // Reference is removed, eligible for GC

        // Object 2: Not eligible for GC

        GarbageCollectionDemo obj = new GarbageCollectionDemo();

    }

}


Calling Garbage Collector

Java allows invoking the garbage collector using:

System.gc();

Runtime.getRuntime().gc();

Note: These methods are merely suggestions to the JVM. Garbage collection is still not guaranteed to run immediately.

Example:

public class Main {

    public static void main(String[] args) {

        Main obj = new Main();

        obj = null; // Make the object eligible for GC

        System.gc(); // Request garbage collection

        System.out.println(“Garbage collection requested.”);

    }

    @Override

    protected void finalize() {

        System.out.println(“Finalize method called.”);

    }

}


The finalize() Method

  • Before an object is removed by GC, the JVM calls its finalize() method.
  • This method can be overridden to release resources before the object is collected.
  • Deprecated: The use of finalize() is discouraged because it is unpredictable and can cause performance issues.

Advantages of Garbage Collection

  1. Automatic Memory Management:
    1. Reduces the risk of memory leaks and dangling pointers.
  2. Simplifies Development:
    1. Developers do not need to explicitly manage memory allocation and deallocation.
  3. Improved Application Stability:
    1. Avoids crashes caused by improper memory handling.

Limitations of Garbage Collection

  1. Non-Deterministic:
    1. The exact timing of GC cannot be controlled, leading to potential performance issues during critical operations.
  2. Overhead:
    1. GC introduces additional CPU overhead.
  3. Not Foolproof:
    1. Memory leaks can still occur if references are unintentionally retained (e.g., in static variables).

Best Practices for Efficient Garbage Collection

  1. Avoid Object Creation in Loops:
    1. Reuse objects when possible to minimize unnecessary object creation.
  2. Release References:
    1. Nullify references when objects are no longer needed.
  3. Use WeakReference or SoftReference:
    1. For objects that can be recreated or are not critical.
  4. Choose the Right Garbage Collector:
    1. Select a GC type that suits the application’s performance and latency requirements.

Conclusion

Garbage collection in Java is a powerful feature that simplifies memory management by automatically reclaiming unused memory. While it provides significant advantages, understanding its behavior and working within its constraints is essential to optimize application performance and avoid memory-related issues.