Automatic memory management means the program never asks for a collection - allocation does. Today you make New collect and retry when the heap is full, so garbage is reclaimed exactly when space runs out.
When New finds no free slot, run a collection and retry the allocation.
Up to now a collection only happened when you called Collect by hand. Real
collectors do not work that way - the program just keeps allocating, and the collector
runs when it has to, precisely when a request finds no room. Today you move the
trigger into New: if there is no free slot (the free list is empty and the cursor
has reached the end), run a collection first, then allocate normally. Any garbage
becomes free space, and the request that would have failed now succeeds.
This is the moment the whole machine becomes automatic. The program allocates the
garbage object a, drops it, keeps b rooted, and later asks for one more object; the
heap is full, so New collects, a’s slot comes back, and the new object lands there.
Notice the reclaimed object is gone for good - the slot now holds a brand-new object,
not the old a. But collection can only help if there is genuinely garbage to reclaim.
The next lesson faces the case where there is not.
func (h *Heap) New(nfields int) (Ref, error) {if len(h.free) == 0 && h.next >= h.Capacity() {h.Collect() // heap is full: reclaim garbage and refill the free list}// ... then allocate from the free list or the cursor as before ...}