r-alloc implements Arena and Slab memory allocation strategies in C++ using mmap for direct page-level memory management. A Node.js bridge via N-API lets backend applications use these allocators for hot allocation paths — bypassing V8's garbage collector entirely for those objects.
Two Strategies
Arena Allocator
Allocates a large contiguous region upfront via mmap(MAP_ANONYMOUS). Individual allocations are bump-pointer: just increment a cursor. Deallocation is free — reset the cursor to zero to reclaim the entire arena. Best for request-scoped allocations that all die at the same time.
// Arena bump allocation (C++)
void* Arena::alloc(size_t n) {
n = align8(n);
if (cursor + n > capacity) throw std::bad_alloc();
void* ptr = base + cursor;
cursor += n;
return ptr;
}
Slab Allocator
Maintains a pool of fixed-size chunks. Allocation pulls from a free-list; deallocation returns to it. Zero fragmentation for uniform object sizes — ideal for objects like connection structs or parsed request headers that are created and destroyed rapidly but at unpredictable times.
The N-API Bridge
N-API (Node-API) is the stable C interface for writing Node.js native addons. r-alloc compiles to a .node shared library that Node.js can require() like any module. From JavaScript, calling alloc.arena.alloc(size) goes through N-API, executes the C++ arena bump, and returns a Buffer wrapping the raw pointer — no copy, no GC involvement.
Benchmarks
Against a synthetic workload of repeated fixed-size allocations and frees in a Node.js request handler:
- Maximum observed latency (P99.9) lower than glibc malloc and V8 heap
- Peak RSS lower due to no GC metadata overhead and predictable page usage
- Mean throughput comparable to V8 for the slab case; higher for arena (reset is O(1))
The gains are most significant at high allocation frequency — GC pause jitter dominates V8's latency distribution at heavy load.
Connection to SAMM
r-alloc is the predecessor to my thesis project SAMM. It proved the N-API bridge approach works and that arena strategies are viable for Node.js hot paths. SAMM extends this by adding the profile-guided selection layer — so instead of the developer choosing which allocator to use per site, the profiler chooses automatically.
Read the companion post: Bypassing V8's GC With N-API and mmap →