Java learning pathSection 13

GC Internals

Understand remembered sets, barriers, concurrent phases, and region-based collection.

1

Remembered Sets

A remembered set records relevant references entering a memory region or generation from outside it. This lets the collector process a subset of the heap without scanning every other region for incoming references.

For example, an old-generation Customer references a young-generation Order. Even if the young collector does not scan all old objects, it must treat that old-to-young link as potentially keeping the Order alive.

Remembered sets are collector-specific; G1 tracks cross-region relationships. The metadata consumes memory and requires maintenance work.

Remembered sets, barriers and concurrent GC phases that let collectors work on parts of the heap.
GC internals overview
2

Card Tables

A card table is compact metadata that divides a heap address range into coarse-grained cards. It can flag cards containing fields whose references may have changed, so the collector examines only relevant areas.

An assignment such as oldObject.child = youngObject may cause a write barrier to mark the card holding that field. A later collection scans selected dirty cards to find cross-generation references.

Cards trade precision for compact metadata: a dirty card does not imply every object on it refers to young objects.

3

Write Barriers

A GC write barrier is small JVM-generated logic associated with certain writes to object references. The collector uses it to maintain metadata or preserve marking correctness while the application mutates references.

The language does not expose the barrier as a method call. Generated code may update a card table, enqueue an old reference for SATB, or do other collector-specific work, and not every write does the same work.

A write passes through the G1 post-write barrier, marks a card dirty, is queued, refined concurrently, and recorded in the per-region remembered set.
G1 stage 1: runtime mutation
Example
class Node { Node next; }

Node oldNode = new Node();
Node youngNode = new Node();
oldNode.next = youngNode; // JVM may execute barrier logic here
4

Read Barriers

A read or load barrier is collector-generated logic associated with retrieving an object reference. Certain relocating collectors use it to make sure the application uses the correct current location or state of an object.

Reading holder.person may involve a compiler-inserted barrier depending on the collector. It is not equivalent to the Java volatile keyword.

A load barrier validates or adjusts a reference, alongside concurrent sweeping gaps and concurrent compaction.
Read barriers, sweeping and compaction
Example
Person p = holder.person; // may involve a load barrier
5

SATB (Snapshot At The Beginning)

Snapshot-at-the-beginning is a concurrent marking technique that preserves the set of objects logically reachable at the start of marking, despite reference updates.

Suppose A references B at the start. The application then executes A.child = C before the collector visits B. A pre-write barrier records the overwritten B so it is not lost from the snapshot.

SATB may retain some floating garbage until a later cycle. G1 and particular Shenandoah modes use SATB-style marking; do not assume every collector does.

SATB keeps the old reference to B after A.child is set to C, next to a concurrent marking timeline with initial mark and remark pauses.
SATB and concurrent marking
6

Concurrent Marking

Concurrent marking traces reachable objects while application threads keep modifying the object graph. To stay correct, collectors combine barriers with brief coordination phases.

Initial-mark and remark phases may require STW pauses, and the exact sequence varies by collector. Concurrent does not mean no pauses.

7

Concurrent Sweeping

Concurrent sweeping identifies and reuses space belonging to dead objects while application threads run. Sweeping does not inherently move surviving objects.

In historical CMS, dead old-generation blocks were swept concurrently after marking and remark, and non-moving reclamation could leave fragmented space. Compaction can consolidate such gaps. Not every modern collector uses concurrent sweeping as its primary mechanism.

8

Concurrent Compaction

Concurrent compaction, also called concurrent relocation or evacuation, moves live objects while application threads execute. The collector must make sure readers and writers keep referring to the correct logical objects.

ZGC and Shenandoah use concurrent relocation with reference and barrier machinery. Merely copying objects without updating references would break the application.

9

Region-based Collection

A region-based collector splits the heap into many independently managed regions instead of treating it as one continuous unit. G1 may select young regions and certain old regions with high expected reclamation value, and region assignment can change.

Benefit: the collector can focus on selected areas and plan evacuation work. Cost: cross-region reference tracking and scheduling metadata.

The G1 cycle: trigger, concurrent marking, collection-set selection, stop-the-world evacuation, copying live objects, then reclaiming regions.
G1 stage 2: collection cycle
10

Pause Time Goals

A pause-time goal is a target the collector tries to meet while balancing throughput, memory, and CPU. It is not a hard real-time guarantee. With the setting below G1 aims for roughly 100 ms, but individual pauses may exceed it under allocation or memory pressure.

Measure p95/p99 application latency alongside actual pause distributions, allocation rate, post-GC occupancy, and CPU use. Reducing one pause may increase GC frequency or CPU overhead.

A region-based heap next to a pause-time goal of 100 ms that is a target rather than a guarantee.
Region-based collection and pause goals
Example
java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -Xmx2g -Xlog:gc* GcDemo