← Concepts

阅读中文版本

Memory Allocator Design

Memory allocators — malloc implementations, runtimes, arenas — decide allocation latency, fragmentation, and cache locality; swapping glibc malloc for jemalloc changes service behavior measurably.

performance

Definition

Allocators mediate between large kernel mappings and program requests. Strategies differ: size-class freelists and thread caches trade per-size memory for lock-free fast paths; arenas reduce cross-thread contention; slab allocation serves fixed object shapes. Fragmentation — external holes, internal padding — and contention are the two costs that allocator choice moves.

Context and scope

Tuned for long-running servers with many threads, allocation-heavy workloads, and fragmentation-sensitive deployments. LD_PRELOAD swapping or runtime flags change the allocator without code changes.

Common misconceptions

  • malloc is malloc everywhere — glibc ptmalloc, jemalloc, tcmalloc, mimalloc differ in thread caches, arena count, and fragmentation behavior by design
  • Fragmentation means memory leaks — fragmentation is unreachable free space between live allocations; leaks are unbounded growth — different bugs, different fixes
  • The allocator cannot affect correctness — bugs like double free and use-after-free interact with allocator hardening features that trade speed for detection

Anti-patterns

  • Multithreaded servers on single-arena allocators serializing every allocation on one lock
  • Mixed tiny and huge allocation patterns producing external fragmentation that looks like a leak in RSS
  • Benchmarking allocation microbenchmarks single-threaded and choosing an allocator whose arena overhead hurts in production

Related concepts

Related examples

Authoritative source

https://jemalloc.net/

What it is

Programs ask for bytes at unpredictable sizes and lifetimes; kernels grant pages in large chunks. The allocator is the layer in between, and its data structures — size classes, freelists, arenas — set the cost curve of every object your program creates.

How it works

Small requests map to size classes with per-thread caches for lock-free allocation; large requests mmap directly. Arenas shard the heap to bound lock contention at the cost of inter-arena fragmentation. Slab allocators carve fixed shapes with free lists embedded in the objects. Hardened modes add guard pages, quarantines, and randomization for exploit resistance.

When to choose

High-thread-count services with allocation-heavy paths, long-lived processes where fragmentation accumulates, and security-sensitive parsing of untrusted input. Measure RSS growth versus live bytes and allocation latency distribution before and after.

Pitfalls

Per-thread caches hold memory invisible to allocation stats — thread churn inflates RSS. Arena count versus NUMA topology mismatches add cross-node traffic. Swapping allocators changes memory layout and can expose latent bugs — double frees that were benign-by-luck become crashes, which is diagnostic value disguised as an outage.