Reachability tells you what to keep; the collector needs the complement - what to reclaim. Today you build Garbage - the live objects the trace did not reach - the exact set every collection frees.
Compute the set of live objects that are not reachable from any root.
Collection is a partition of the live objects into two groups: the reachable ones
to keep and the garbage to reclaim. You have the reachable set; the garbage is
simply its complement within the census - every live object the trace did not reach.
Garbage computes LiveRefs minus Reachable, in ascending order for a clean
assertion.
This is the decision a mark-sweep collector acts on: keep the reachable, free the garbage. Notice the two sets are exhaustive and disjoint - together they are exactly the live objects, with nothing double-counted and nothing missed. An object is garbage the instant the last path to it from a root disappears, whether that happened because a root was removed or a reference was overwritten. Next lesson makes the case that this trace-based definition catches garbage that reference counting never can.
// garbage = live objects minus the reachable setfunc (h *Heap) Garbage() []Ref {reach := h.Reachable()var g []Reffor _, r := range h.LiveRefs() { // ascendingif !reach[r] { g = append(g, r) }}return g}