JVM & Memory

97. Garbage Collectors in Modern Java

Modern Java features multiple production garbage collectors: G1GC (default throughput/pause balance), Generational ZGC (sub-millisecond pauses at terabyte scale), and Shenandoah (concurrent compacting).

Java 21+ (G1GC, ZGC, Shenandoah)

Explanation

HotSpot provides several garbage collector implementations tailored for different latency and throughput requirements. G1 (Garbage-First) has been the default collector since Java 9. It partitions the heap into equal-sized regions, dynamically assigns them to Eden, Survivor, or Old generations, and prioritizes regions with the most reclaimable garbage within a user-configurable pause target (-XX:MaxGCPauseMillis=200).

For ultra-low-latency workloads, ZGC (Z Garbage Collector) performs all heavy GC work concurrently with running application threads: marking, relocation (compaction), and reference processing. Pauses do not scale with heap size and consistently stay under 1 millisecond, even on multi-terabyte heaps. Java 21 introduced Generational ZGC (JEP 439, enabled via -XX:+UseZGC -XX:+ZGenerational), separating young and old objects to achieve higher allocation throughput while preserving sub-millisecond pauses.

Shenandoah is another concurrent compacting collector that keeps pause times independent of heap size by evacuating objects concurrently using Brooks pointers or load-reference barriers. Parallel GC (-XX:+UseParallelGC) remains the optimal choice for non-interactive batch processing where raw throughput matters more than pause latency.

Example

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;

public class GcInspection {
    public static void main(String[] args) {
        System.out.println("Active Garbage Collectors in current JVM:");
        for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
            System.out.printf("  Collector: %-25s | Count: %d | Total Pause Time: %d ms%n",
                gc.getName(),
                gc.getCollectionCount(),
                gc.getCollectionTime());
        }

        // Modern JVM flags quick reference:
        // Default (Java 9+):     -XX:+UseG1GC -XX:MaxGCPauseMillis=200
        // Low Latency (Java 21): -XX:+UseZGC -XX:+ZGenerational
        // High Throughput Batch: -XX:+UseParallelGC
        // Lightweight/Containers:-XX:+UseSerialGC
    }
}

Sources