Comment by deathanatos
2 hours ago
> just because you only collect in the new generation doesn't mean that you only trace the new generation.
Well, then I suppose you're saying the up-thread comment is wrong?
TFA:
> Every one of those pointers has to be followed on every cycle
The comment:
> That's a strange thing to assert, having acknowledged the existence of generational GC.
Which would imply that's not the case, i.e., that we're not considering every pointer in every GC sweep. (Which, again, I thought was largely the point of generational GCs: to make sweeps cheap by not considering every pointer.)
I guess if it's really the sweep that's the expensive part, then perhaps doing a full walk is fine.
> generational GC design is to include the old generation in the GC roots so you don't need to examine everything in the new generation
I'm assuming roots (stack references to objects) are separate from generations (which heap objects belong to).
I suppose if you added old objects to the set of roots, that'd also solve it, but that's the same as "every one of those pointers has to be followed on every cycle".
The sibling post thinks writes are made more expensive by tainting/young-ifying objects that get written to. In that way, we prevent an old object from ever pointing at a new one — at the cost of writes now being more than a write.
Edit: Yeah, here's [a note](https://chromium.googlesource.com/v8/v8/+/refs/heads/13.3.25...) about how Chrome implements it. There is additional book-keeping and cost to writes.
> 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.)