7.5. Concurrent mark
A full collection may run its mark phase concurrently with mutators. Minor collection, explicit rok_gc_collect, and evacuation are always stop-the-world (7.3).
7.5.1. When
ROK_GC_CONCURRENT | Full collection |
|---|---|
auto (default) | Concurrent mark if old objects total 32 MiB or more |
always | Always concurrent mark |
off | Always STW |
An unset or empty variable has its default. A value outside those listed prints one warning line on stderr naming the variable, the value and the accepted values, and the variable has its default.
7.5.2. Phases
- Initial pause (STW). Run one minor collection and take a snapshot of the roots at a safepoint. Set the global
MARKINGflag. - Concurrent mark. A single marker thread marks starting from the snapshot. Mutators keep running.
- Final pause (STW). Drain the SATB buffers, rescan the roots, and sweep. Clear
MARKING.
7.5.3. SATB barrier
Snapshot-at-the-beginning (Yuasa), per object. It reuses the generational write barrier (7.4.2) as is.
- The slow path on the first write to an
UNLOGGEDobject, whenMARKINGis set, records all of that object's current references in the SATB buffer (TLSrok_tls_satb_cursor/rok_tls_satb_limit, 8.3). - While recording, it sets the header's
SATBbit. A competing store to the same object waits until that bit is cleared. - So the barrier code the compiler emits is the same whether or not concurrent mark is in use.
7.5.4. Allocation and collection
- Allocation during mark is black at line granularity (objects in that line are treated as live). Objects allocated during mark are young after mark finishes.
- No minor collection happens during mark. If allocation demands a collection, the ongoing mark is finished.
- Evacuation happens only in STW full collections. If the heap is fragmented after a concurrent mark, the next full collection is done as STW with evacuation.