Generational collection: remember edges across the boundary
Explain partial-heap tracing, old-to-young references, remembered sets, and why write barriers preserve collection correctness.
On this page
The question for today
What you’ll understand
- Explain why a young-generation collection needs references originating in older objects.
- Distinguish a remembered-set barrier from a concurrent-marking invariant.
- Estimate card-table metadata and conservative scanning coverage using explicit assumptions.
A generational collector tries to reclaim a selected part of the heap without repeatedly tracing every older object. That shortcut creates a correctness obligation: a young object may be reachable through an old object that the collection does not otherwise inspect. Write barriers record enough information about changing references to keep such cross-boundary paths visible.
Partial collection changes the starting set
Many workloads allocate objects that soon become unreachable, motivating a young allocation region that can be collected frequently. Objects surviving selected collections may be promoted according to the runtime's policy. This is a workload hypothesis and implementation strategy, not a theorem that every newer object dies sooner than every older one. Long-lived input batches, cached request objects, and persistent graph construction can produce very different survivor patterns. Measure age and retention rather than treating promotion as an application-level measure of usefulness.
Suppose a root reaches an old object A, and A contains the only reference to young object B. A collector scanning only young roots and young objects would miss B if it ignored A's edge. Scanning the entire old heap would recover correctness but defeat much of the partial-collection benefit. A remembered set records relevant edges or conservative source regions. The young collection then treats their young targets as additional starting points and traces within its collection scope. A false-positive remembered entry can add work; losing a required live edge can corrupt the program.
A write barrier maintains information
A write barrier is runtime work associated with a reference mutation. In a card-table design, the heap is divided into fixed-size address regions called cards; a store can mark the source card dirty. Later scanning that card discovers relevant references. This stores less information than recording every target exactly, at the cost of inspecting additional bytes or objects. Other runtimes use different remembered-set representations and filtering. A barrier may be inlined, batched, or optimized when the compiler can prove the recording unnecessary.
Generational barriers and concurrent-marking barriers address different invariants, though one implementation may combine their work. During concurrent tracing, a mutator can change edges while marking progresses; a particular algorithm may need to record a newly installed reference, preserve an overwritten reference, or enforce another specified condition. Do not transfer the details of one algorithm to all collectors. At a native-code boundary, writes to managed reference fields must use the runtime's supported interfaces so its required barriers and root tracking are not silently bypassed.
Account for both mutation and survival
A workload updating many old reference fields can create significant barrier and remembered-set work even with a small allocation rate. A workload retaining most young allocations can make young collections expensive because many objects must be traced or evacuated. Diagnose those mechanisms separately: record allocation rate, survivor or promotion volume, dirty-region work where available, and pause distribution. Reducing the frequency of one phase can shift work elsewhere. A larger young region may reduce collection frequency while increasing the amount considered in a single collection.
The probability lab isolates a hypothetical survivor fraction, not barrier execution. Set n=20 and p=0.10, predicting two survivors on average; increase p to 0.50 and predict ten. This compares equal-sized independent objects in one artificial cohort. The actual controls cannot change generation size, promotion age, card width, or mutation rate, and real object lifetimes are often dependent. Explain why a higher survivor fraction may increase copying or tracing work, then draw the old A→young B edge separately to show a correctness requirement that the probability bars cannot represent.
Work it through
Budget a fictional card table
A teaching collector covers 16 MiB of old-region address space with 512-byte cards and one metadata byte per card. Exactly 640 distinct cards are dirty. These are hypothetical parameters, not a runtime default.
There are 16 × 1,048,576 / 512 = 32,768 cards. One byte per card gives 32,768 metadata bytes, or 32 KiB.
The dirty cards cover at most 640 × 512 = 327,680 bytes, or 320 KiB. Some cards may contain no currently relevant old-to-young edge.
To preserve a live young target referenced only by an old object, the collector must discover that edge through its remembered information or another sound mechanism. A small table or fast scan is useful only if that coverage invariant holds.
The example separates 32 KiB of table metadata from at most 320 KiB of dirty-card address coverage. Neither quantity equals live young payload or proves a pause duration.
The living notebook
Explore the model
Interactive lab · probability
Survivors change partial-collection work
Keep n=20 and change p from 0.10 to 0.50 in the exact binomial model. Predict a mean survivor count rising from 2 to 10. This independent cohort illustration does not model generations, promotion, remembered sets, write barriers, or correlated object graphs.
- Mean · np
- 5
- Variance · np(1−p)
- 2.5
- Total probability
- 1
These are exact binomial probabilities for independent trials with one fixed success probability. Playback tours the distribution; it does not resample outcomes. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forSurvival fraction affects potential work, while remembered boundary references are a separate correctness requirement.
Pause & reason
Check your understanding
Your turn
Try it yourself
In the same fictional 512-byte-card scheme, 1,024 distinct dirty cards cover how much address space? Does doubling dirty-card count necessarily double the number of young live objects?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Multiply card count by card width, then distinguish source-region coverage from target reachability.
Compare with the solution
The coverage bound is 1,024 × 512 = 524,288 bytes, or 512 KiB. It does not imply twice as many live young objects: several cards may reference one target, dirty cards can contain stale entries, and some contain no relevant edge after mutations. Runtime scanning and filtering determine actual work.
Keep the idea
Take it with you
- A partial collector must include live references crossing into its collection scope.
- Write barriers maintain algorithm-specific information; their purposes are not interchangeable.
- Mutation rate, dirty coverage, and survival fraction describe different sources of collection work.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.