Skip to main content

ServerAllocator

Type Alias ServerAllocator 

Source
pub type ServerAllocator = MiMalloc;
Expand description

The allocator every gunnar that serves is built on.

A #[global_allocator] is the executable’s to choose — bench’s stages.rs says so in its own header, and cargo enforces it: two of them in one binary is a hard error. So this crate does not install one. It publishes the choice as a type, and each serving binary spends one line on the declaration:

ⓘ
#[global_allocator]
static ALLOC: gunnar_server::ServerAllocator = gunnar_server::SERVER_ALLOCATOR;

That is one implementation applied to the heap with the grain of the language rather than against it. The choice lives in exactly one place, so the appliance, the gunnar-solo/gunnar-service builds and the bench’s git-store-serve cannot drift onto different allocators — and bench’s counting probes, which must install a wrapper of their own, wrap this rather than System, so alloc_mib_* describes the allocator that actually ships. Installing it in the library instead looks tidier for exactly as long as it takes someone to build a probe: it collided with stage-probe’s CountingAlloc on the first compile.

The type is defined either way — System when the feature is off — so no declaration site needs a #[cfg].

§Why, with the numbers

znippy’s resolver used to retain its whole read arena. Freeing it (znippy 0f14d9b) took anon-after-seed from 4481 MB to 438 MB and cost 78% on clone CPU — 1.47 s to 2.62 s on a 352 396-object clone. The obvious reading is that the eviction forces re-resolution. It does not; the clone path never calls the resolver. The retained arena was an accidental pre-warmed malloc pool for the clone’s own ~2 GB of allocations, and giving it back put glibc’s malloc on the critical path for every clone thereafter. Bisected: a build that frees but does not refcount reproduces the whole regression, so the cost is the not-leaking, not the counting.

Four-way grid, one box, interleaved, quiet, steady state:

resolverallocatorclone CPUanon after seed
leakingglibc1.47 s4481 MB
freeingglibc2.62 s438 MB
leakingmimalloc1.18 s1767 MB
freeingmimalloc1.17 s701 MB

The last row beats the leaking build’s best cell on both axes at once, and with a competent allocator the two resolvers are within 0.01 s — the regression was never in znippy. It is user-space allocator cost and not page faults: system time is identical (0.14 s) and suppressing trim with M_TOP_PAD removed 20 762 faults while moving CPU by 0.04 s.

Opt out with --no-default-features; see this crate’s manifest for what that buys and what the dependency budget does and does not actually forbid.

Aliased Type§

pub struct ServerAllocator;