Skip to content
About
Main content

Lifetime is phase-structured

What does general-purpose memory management charge for, and what do phase-structured lifetimes let you stop paying?

General-purpose memory management charges for arbitrary lifetime. malloc must let you free any object at any time in any order. The garbage collector must let any reference reach any object. That one requirement generates all of its costs: per-object headers, free lists, of neighbouring free blocks, , and, for a tracing collector, a traversal proportional to what survives.

But data-engineering workloads almost never need arbitrary lifetime. They have phases: a batch, a tuple, the build side of a join, a query. Inside a phase, allocations are born together and die together.

The bets differ only in what the phase is and what happens if you are wrong.

MechanismFreedom given upBought with itFailure when the bet is wrong
/ regionfree in arbitrary order~50× cheaper allocation, bounded fragmentationdangling pointer, silent
Off-heapruntime-proved liveness invisible to the collector, byte-level layoutleak or use-after-free, silent
GC tuningnothing (you stay on the runtime)a position on the pause/throughput trade-offpause frequency blows up non-linearly
Arrow-style poolingarbitrary object shape sharing, computable footprintmemory pinned by the slowest consumer
Interning / dictionaryvalue independencerepetition becomes integersunbounded dictionary growth
bindingplacement freedomlocal memory bandwidthbinding fights the scheduler