skip to content

Why can the largest free block keep shrinking in a heap whose manager is able to relocate objects to consolidate free space?

level: seniorimportance: nice to knowfreq 28%

answer

  1. moving is not always allowed
  2. someone outside holds the address
  3. immovable tenant, stranded unit
  4. evacuation is all or nothing
  5. consolidation skips pinned units

basics

~10 s

Relocation needs permission. An object whose address has escaped the manager, or that is too costly to copy, is pinned in place, and one immovable object stops its whole unit being emptied and merged.

solid answer

~40 s

Moving an object means copying its bytes and rewriting every reference to it, which the manager can do only for references it knows about. An address handed to a transfer running outside the managed heap has escaped that bookkeeping, so the object must stay put until the transfer is done; very large objects are often excluded on cost grounds too. Relocating managers work a unit at a time and free a unit by evacuating everything live out of it, so one immovable tenant strands the whole unit and its free space stays split off from everything else. Enough long-lived pins, spread across enough units, and consolidation reclaims almost nothing: total free stays flat while the largest contiguous free block falls.

go deeper

for a junior

Know that some objects cannot be moved while something outside the memory manager is using their address. Memory that is free around such an object cannot always be joined up with the free space next door.

for a middle

Explain why relocation requires rewriting every reference, and why an address that has escaped the manager's bookkeeping forces the object to stay put. Then explain that units are emptied all-or-nothing.

for a senior

Diagnose it: measure what a consolidation pass actually merges against the free bytes available, watch skipped units, and correlate the symptom with the code paths that hand addresses out rather than with uptime.

for a principal

Treat pin lifetime and pin scatter as design constraints. Decide whether the service reuses a small fixed set of immovable buffers or accepts a steadily less consolidatable heap, and make that an explicit rule rather than an accident.

## Consolidation depends on permission to move A manager that relocates objects fixes shattered free space by copying live objects together and leaving one large run behind. Moving an object means copying its bytes and then updating **every reference that points at it**, so they name the new address. The manager can do that for references it knows about: fields of other objects, the roots it enumerates, its own bookkeeping. It cannot do it for an address that has escaped that bookkeeping — one written into a structure outside the managed heap, or handed to a device or kernel transfer that will read it later. For as long as such an address is outstanding, the object must stay exactly where it is. That state is **pinning**. ## What ends up pinned - Buffers whose address was handed to an outside transfer, for the duration of that transfer. - Objects reachable from a foreign structure that the manager does not walk and cannot rewrite. - Objects the manager has decided not to move on cost grounds — very large ones in particular, where copying would dominate the cycle. - Objects pinned by an explicit request in the program, for as long as the program holds the pin. The first of these is usually short-lived and harmless. The damage comes from **long-lived** pins, and from pins spread thinly across many units. ## One immovable tenant strands a whole unit Relocating managers work a unit at a time. To free a unit they evacuate every live object out of it and then take the whole unit back as one run. The rule is all-or-nothing: 1. Pick a unit with little live data — a good candidate, because evacuation cost is proportional to what must be copied. 2. Copy each live object out to a destination unit and fix the references that named it. 3. If even one object cannot be copied, the unit cannot be emptied. Its free space stays where it is: split, scattered, and separate from every other unit's free space. A heap with a few percent of its units pinned loses far more than a few percent of its consolidation ability, because the manager chooses units by how little is live in them, and a pinned buffer sitting in an otherwise empty unit is exactly the candidate it wanted. The measurable result is the signature this leaf is about: **total free flat, largest contiguous free block falling**. | Observation | Plain hole accumulation | Pins blocking consolidation | |---|---|---| | Manager relocates objects | Consolidation recovers runs each cycle | Consolidation runs and recovers little | | Largest free block after a cycle | Rises back towards its old value | Stays flat or keeps falling | | Correlation | Broad; grows with uptime | Tracks the phases that hand addresses out | ## How to confirm it - Compare the free bytes before a consolidation pass with how much the pass actually merged. A large gap means the pass was blocked, not idle. - Count units the manager skipped as unevacuatable, where it reports that. A rising count is direct evidence. - Correlate the failures with the phases that hand object addresses to outside transfers. A symptom that tracks that traffic, rather than uptime alone, points at pins. - Route the transfers through a copy into space the manager never relocates, and see whether the largest free block recovers. A change that makes the symptom disappear is the strongest evidence available from outside the code. ## Why this one is easy to miss The intuition that a relocating manager cannot suffer from shattered free space is nearly right, and nearly right is the dangerous kind. It holds for ordinary objects and fails for exactly the objects a program is most likely to make large: the buffers it shares with the outside world. Those are simultaneously the biggest, the most likely to be pinned, and the ones whose allocation fails first when large runs run out. A service can therefore be failing on precisely the allocations that its own pinning behaviour made impossible, while every graph on the wall says the heap has room. The practical rule that follows is to keep pins short and few, and to **concentrate** what must be immovable instead of scattering it. A small set of long-lived buffers reused for every transfer strands a small, fixed set of units; a fresh pinned buffer per request strands a new unit each time and leaves the manager with steadily less it is allowed to touch. Ecosystems differ in how much of this they expose — some make pinning explicit and bounded, others do it implicitly on your behalf — but the accounting is the same everywhere: consolidation can only reclaim what it is permitted to move.

  • How would you tell pinning apart from ordinary hole accumulation?
    Look at what consolidation achieves rather than whether it runs. If passes complete but merge far less than the free bytes suggest, and the units skipped as unevacuatable keep rising, the manager is being blocked. A symptom that tracks the phases handing addresses to outside transfers, rather than uptime alone, confirms it.
  • Why do very large objects behave like pins even when no outside code holds their address?
    Because managers usually exclude them from relocation on cost grounds: copying a huge object could dominate the cycle, so it is placed in space sized for it and left alone. The effect on free-space shape is identical to a pin — the run it occupies is fixed, and it bounds what the largest free block can become.

saying these in an interview costs you the question

  • Assumes a manager that relocates objects can never fragment
  • Treats pinning as a pure copying cost with no space effect
  • Believes consolidation covers the whole heap regardless of pins
  • Watches only total free bytes, which stays flat throughout
  • Says an object can move while an outside transfer reads its address