☕ Java Q58 / 162

What is G1 garbage collector?

AI-Powered Answer ✓ Answered

The Garbage-First (G1) collector is a server-style garbage collector introduced in Java 7 and became the default collector in Java 9. It is designed to be a long-term replacement for the Concurrent Mark-Sweep (CMS) collector, targeting applications with large heaps (4GB or more) and requiring predictable pause times.

Purpose and Design Goals

G1's primary goal is to achieve high throughput while also meeting a user-defined pause time target. Unlike previous collectors that operated on the entire heap (like parallel or CMS), G1 partitions the heap into a set of equal-sized regions, typically 1MB to 32MB depending on the heap size.

Key Features and Mechanism

  • Region-Based Heap: The heap is divided into a large number of fixed-size regions. These regions can dynamically be assigned roles like Eden, Survivor, or Old generation.
  • Generational and Concurrent: G1 is still a generational collector, meaning it segregates objects into young (Eden, Survivor) and old generations. It also performs many of its tasks concurrently with the application threads.
  • Pause Time Targets: Users can specify a target maximum pause time (e.g., -XX:MaxGCPauseMillis=200). G1 attempts to meet this goal by prioritizing garbage collection in regions that contain the most garbage (hence 'Garbage-First').
  • Humongous Objects: Objects that occupy more than half a region are called Humongous objects. They are allocated directly in Old regions and managed specially.
  • Remembered Sets (RSets): Each region tracks incoming references from other regions using a data structure called a Remembered Set. This allows G1 to collect regions independently without scanning the entire heap.
  • Evacuation Pause: The actual copying of live objects from a set of selected regions (called the 'collection set') to new, empty regions is performed during an Evacuation Pause, which is a stop-the-world (STW) event, but its duration is controlled by the pause time target.

G1 GC Cycle

The G1 cycle generally involves several phases, some of which are concurrent and some are 'stop-the-world' (STW):

  • Young Collection: Happens frequently, collecting Eden and Survivor regions. This is a STW pause.
  • Concurrent Marking: Initiated when the old generation occupancy reaches a certain threshold. It identifies live objects in the old generation while the application runs. This phase includes initial mark (STW), concurrent mark (concurrent), remark (STW), and cleanup (concurrent/STW).
  • Mixed Collection: After concurrent marking, G1 performs mixed collections. These pauses include both young generation regions and a selected set of old generation regions with the most reclaimable space. This is a STW pause.

Advantages of G1

  • Predictable Pause Times: Aims to meet user-defined pause time goals, making it suitable for interactive applications.
  • Handles Large Heaps: Efficiently manages heaps of 4GB and larger.
  • No Compaction Issues: Unlike CMS, G1 is a compacting collector, meaning it eliminates fragmentation by copying live objects to new regions.
  • Replaces CMS: Offers an alternative to CMS for applications sensitive to latency, without the fragmentation issues of CMS.

When to Use G1

G1 is generally recommended for applications that:

  • Run on multi-processor machines with large memory volumes.
  • Require stable and predictable pause times.
  • Have objects that live for a long time (large old generation).
  • Experience frequent minor garbage collections.

Enabling G1 (JVM Options)

Since Java 9, G1 is the default garbage collector. For older versions (Java 7 and 8), you can explicitly enable it using JVM flags:

bash
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-Xmx8g

The -XX:MaxGCPauseMillis flag is crucial for G1 as it sets the desired maximum pause time (in milliseconds) that the collector will attempt to achieve.