Comment by aw1621107
2 hours ago
> Which would imply that's not the case, i.e., that we're not considering every pointer in every GC sweep.
I think "every one of those pointers has to be followed on every cycle" as a blanket statement is not correct. It's true for some GC designs and not true for others.
> I'm assuming roots (stack references to objects) are separate from generations (which heap objects belong to).
Roots are just where you start tracing from. You can include older generations in them (or even subsets thereof), but you're by no means required to.
> but that's the same as "every one of those pointers has to be followed on every cycle".
Sure, but my point there was just that just collecting the new generation doesn't have to imply that you're only tracing the new generation. I guess I should have added a "necessarily" somewhere in my original comment.
> There is additional book-keeping and cost to writes.
From my understanding the bookkeeping there is effectively to be able to determine the set of roots to use when tracing/collecting the new generation.
Generally speaking, whenever you trace into the old generation, you stop and back out. Given a young generation object with pointer fields, you don't know which of them are also young and which are old, unless you examine them, which is tracing. So the tracing pokes into the surface of the sediment generation, so to speak.
Then if the language allows mutation of objects, special consideration has to be given to old objects that were mutated to point to new ones. You can treat those as additional roots; the graph of young objects reachable from a mutated old object is reachable. (Considered so on the assumption of the old object being reachable, which we can only disprove by doing a full scan.)