The Runtime Theory
mediumApplicationDSA#allocation#memory#heap

What happens when you allocate an object?

Probes whether you know allocation is a pointer bump in a thread-local region — not a syscall — plus heap expansion, GC interaction, and why allocation order shows up in traces.

The Runtime Theory Team2 min readasked at google · amazon · microsoft · cloudflare

This question separates people who think allocation is slow because it's "going to the OS" from people who know the actual fast path: a pointer bump into a thread-local heap region. The interviewer wants the fast path, the slow path, and when the fast path stops being free.

The mental model: allocation is two different operations. The fast path is giving you the next contiguous block of memory out of an already-mapped, already-zeroed region. The slow path is acquiring more memory when the region runs out.

Fast path walkthrough. In a modern managed runtime or allocator, each thread owns a thread-local allocation buffer (TLAB in the JVM, bump pointer in .NET, tcache in glibc). An allocation is: check current + size <= limit, if so, take current, bump current by the size rounded to the alignment (8 or 16 bytes), optionally zero the memory (C# does; Java relies on zeroed pages from the OS). No lock, no syscall, ~10–20 instructions. For small objects this is faster than the linked-list walk a textbook malloc implies.

Slow path walkthrough. When the TLAB is exhausted, the thread requests a new region from the runtime's global heap. That may trigger a GC (to reclaim dead objects before growing), or an OS-level call: mmap/brk for native allocators, which reserves address space and lazily maps physical pages on first touch — that first-touch page fault is where the real cost is. If the heap is out of the reserved region, the allocator may ask the OS for more, and the OS may hand back a region that requires TLB entries, page table work, and zeroing.

Tradeoffs and edge cases worth naming:

  • Allocation is not deallocation. In a GC runtime, freeing is deferred to collection — allocation is cheap precisely because cleanup is batched.
  • Size classes and freelists: large allocations (usually > a threshold like 128 KB) skip the TLAB and get mmap'd directly, so their lifespan is page-aligned.
  • Locality: bump allocation means sequentially allocated objects are adjacent in memory — cache-friendly, which is why object pools are less necessary in modern runtimes.
  • Zeroing costs: allocations after a GC compaction may need explicit zeroing, and that shows up in traces as increased latency.

A strong closing: "For the common case, allocation is a pointer bump in a thread-local region; the expensive parts — syscalls, zeroing pages, GC — only happen when that region runs out."

This answer walks

Follow-ups they'll push on

  1. 01When does an allocation actually hit the operating system?
  2. 02Why is bump allocation faster than free-list allocation?
  3. 03What happens to the object when the function returns?
  4. 04How do thread-local allocation buffers avoid locking?

More interviews in this topic

One dispatch a week

The trace behind each question, the tradeoff that explains it, and one technical dispatch per week — no noise.

One technical dispatch per week. No noise.