custom-allocators — Claude Code skill: what it does, how to install
Guides agents through designing custom C and Rust memory allocators, tuning jemalloc or mimalloc, and measuring heap fragmentation.
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a claude-codeWhat custom-allocators does
The skill equips coding agents with reference implementations for fixed-size pool allocators and bump arenas in C. Instead of routing every allocation through generic libc malloc, it shows how to use linear arenas for per-request lifetimes where an entire block resets at once.
It covers runtime configuration for jemalloc and mimalloc via LD_PRELOAD alongside environment flags like MALLOC_CONF. For Rust projects, it demonstrates implementing the GlobalAlloc trait to track allocations or run in #![no_std] targets.
Memory leaks in arenas happen when resets are skipped between loop iterations or server frames. In Rust, passing a mismatched Layout to dealloc triggers undefined behavior, so the skill notes storing size and alignment alongside raw pointers.
What it helps with
- implement a fast O(1) fixed-size block pool in C
- build a request-scoped bump arena allocator with reset
- tune jemalloc dirty page purging via MALLOC_CONF
- implement the Rust GlobalAlloc trait for allocation tracking
Example prompts for the agent
- Write an aligned bump arena allocator in C with an arena_reset function
- Show the MALLOC_CONF settings to tune dirty page decay in jemalloc
- Implement a tracking allocator in Rust using the GlobalAlloc trait
How to install custom-allocators
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a claude-code2Manually: put the files in place
~/.claude/skills/custom-allocators/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/custom-allocators/
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a codex2Manually: put the files in place
.agents/skills/custom-allocators/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a cursor2Manually: put the files in place
.cursor/skills/custom-allocators/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install mohitmishra786/low-level-dev-skills custom-allocators2Manually: put the files in place
.github/skills/custom-allocators/SKILL.md1Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a gemini-cli2Platform CLI
gemini skills install https://github.com/mohitmishra786/low-level-dev-skills --path skills/allocators/custom-allocatorsManually: put the files in place
.devin/skills/custom-allocators/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about custom-allocators
How do I install custom-allocators in Claude Code?
Run npx skills add mohitmishra786/low-level-dev-skills --skill custom-allocators -a claude-code in your terminal. You can also place the file directly at ~/.claude/skills/custom-allocators/SKILL.md.
What does custom-allocators do?
It provides patterns and code templates for memory strategies like pools and arenas. It also includes tuning guides for production allocators such as jemalloc and mimalloc.
How does the arena allocator handle individual deallocations?
It does not support individual frees. Memory is claimed by incrementing an offset pointer, and all allocated space is recycled simultaneously by resetting the offset to zero.
Source text
SKILL.md · MIT
---
name: custom-allocators
description: Custom allocator skill for memory allocation strategies. Use when implementing pool/slab/arena allocators, tuning jemalloc/mimalloc, writing Rust GlobalAlloc, or benchmarking allocator performance. Activates on queries about jemalloc, mimalloc, tcmalloc, arena allocator, GlobalAlloc, or fragmentation.
---
# Custom Allocators
## Purpose
Guide agents through memory allocator design and tuning: pool/slab/arena/buddy taxonomy, jemalloc internals and `MALLOC_CONF`, mimalloc design, tcmalloc thread-caching, writing a simple pool allocator in C, Rust `GlobalAlloc` trait, fragmentation metrics, and benchmarking.
## When to Use
- Replacing malloc for latency-sensitive or embedded workloads
- Tuning jemalloc/mimalloc for server heap behavior
- Implementing arena allocation for request-scoped or frame-based lifetimes
- Writing a Rust custom global allocator for `no_std` or performance
- Diagnosing heap fragmentation (internal vs external)
- Benchmarking allocator throughput and latency
## Workflow
### 1. Allocator taxonomy
```
Allocator types
├── Pool/fixed-size — O(1) alloc/free, fixed block sizes
├── Slab — kernel-style, cache-friendly size classes
├── Arena/bump — fast alloc, bulk free (reset arena)
├── Buddy — power-of-two blocks, low fragmentation for large allocs
└── General (malloc) — jemalloc, mimalloc, tcmalloc
```
### 2. Simple pool allocator in C
```c
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct pool_block {
struct pool_block *next;
} pool_block_t;
typedef struct {
void *memory;
size_t block_size;
size_t num_blocks;
pool_block_t *free_list;
} pool_t;
int pool_init(pool_t *p, size_t block_size, size_t num_blocks) {
p->block_size = block_size < sizeof(pool_block_t) ?
sizeof(pool_block_t) : block_size;
p->num_blocks = num_blocks;
p->memory = aligned_alloc(64, p->block_size * num_blocks);
if (!p->memory) return -1;
p->free_list = NULL;
for (size_t i = 0; i < num_blocks; i++) {
pool_block_t *blk = (pool_block_t *)((char *)p->memory + i * p->block_size);
blk->next = p->free_list;
p->free_list = blk;
}
return 0;
}
void *pool_alloc(pool_t *p) {
if (!p->free_list) return NULL;
pool_block_t *blk = p->free_list;
p->free_list = blk->next;
return blk;
}
void pool_free(pool_t *p, void *ptr) {
pool_block_t *blk = (pool_block_t *)ptr;
blk->next = p->free_list;
p->free_list = blk;
}
```
### 3. Arena allocator
```c
typedef struct {
char *base;
size_t capacity;
size_t offset;
} arena_t;
void *arena_alloc(arena_t *a, size_t size, size_t align) {
uintptr_t cur = (uintptr_t)(a->base + a->offset);
uintptr_t aligned = (cur + align - 1) & ~(align - 1);
size_t padding = aligned - cur;
if (a->offset + padding + size > a->capacity)
return NULL;
a->offset += padding + size;
return (void *)aligned;
}
void arena_reset(arena_t *a) { a->offset = 0; }
```
Use per-request arenas in servers — reset after response, no per-object free.
### 4. jemalloc tuning
```bash
# Use jemalloc as system allocator
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 ./myapp
# Runtime tuning
export MALLOC_CONF="background_thread:true,dirty_decay_ms:1000,muzzy_decay_ms:1000"
# Profiling build
# ./configure --enable-prof
export MALLOC_CONF="prof:true,prof_active:true,lg_prof_sample:19"
```
jemalloc concepts:
- **Size classes** — rounded allocation sizes
- **tcache** — per-thread cache for hot sizes
- **arenas** — reduce contention across threads
```bash
# Statistics
export MALLOC_CONF="stats_print:true"
# prints on exit, or:
mallctl("epoch", ...); mallctl("stats.allocated", ...);
```
### 5. mimalloc
```bash
# Use mimalloc
LD_PRELOAD=/usr/lib/libmimalloc.so ./myapp
# Environment options
export MIMALLOC_SHOW_STATS=1
export MIMALLOC_PAGE_RESET=1
```
mimalloc hierarchy: segment → page → block. Generally lower metadata overhead than jemalloc.
```bash
# Statistics at exit
MIMALLOC_SHOW_STATS=1 ./myapp
```
### 6. tcmalloc thread-caching
```bash
LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4 ./myapp
# Environment
export TCMALLOC_SAMPLE_PARAMETER=524288 # sampling profiler
```
Per-thread caches for small objects; central heap for larger allocations.
### 7. Rust GlobalAlloc
```rust
use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering};
struct TrackingAllocator;
static ALLOCATED: AtomicUsize = AtomicUsize::new(0);
unsafe impl GlobalAlloc for TrackingAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let ptr = System.alloc(layout);
if !ptr.is_null() {
ALLOCATED.fetch_add(layout.size(), Ordering::Relaxed);
}
ptr
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
System.dealloc(ptr, layout);
ALLOCATED.fetch_sub(layout.size(), Ordering::Relaxed);
}
}
#[global_allocator]
static GLOBAL: TrackingAllocator = TrackingAllocator;
```
For `#![no_std]` with `alloc` crate, implement `GlobalAlloc` without `System`.
### 8. Fragmentation metrics
| Type | Definition | Detection |
|------|------------|-----------|
| Internal | Allocated block larger than requested | Allocator stats; size class rounding |
| External | Free memory not usable for request | `mallinfo`/`malloc_info`; RSS vs heap |
```bash
# glibc malloc_info
malloc_info(0, stdout);
# jemalloc
jeprof --show_bytes ./myapp jeprof.heap
```
### 9. Benchmarking
```bash
# mimalloc bench (if built from source)
cd mimalloc && mkdir build && cd build
cmake .. && make
./mimalloc-bench
# Custom microbenchmark pattern
perf stat -e cycles,instructions ./allocator_bench --threads 8 --size 64
```
Compare: single-thread alloc/free, multi-thread contention, mixed size distribution.
## Common Problems
| Symptom | Cause | Fix |
|---------|-------|-----|
| Pool alloc returns NULL | Free list exhausted | Increase pool size; leak check |
| jemalloc RSS won't drop | Dirty page decay slow | Lower `dirty_decay_ms`; `madvise` |
| Arena OOM | No reset between phases | `arena_reset` or chain arenas |
| Rust allocator UB | Wrong Layout in dealloc | Store size/align with allocation |
| Worse perf with mimalloc | Wrong workload fit | Benchmark; try jemalloc |
| High external fragmentation | Long-lived mixed sizes | Segregate by lifetime; pools |
## Related Skills
- `skills/allocators/numa-programming` — NUMA-aware allocation
- `skills/rust/rust-no-std` — custom allocators in embedded Rust
- `skills/profilers/heaptrack` — allocation hotspot profiling
- `skills/profilers/valgrind` — heap leak detection
- `skills/low-level-programming/cpu-cache-opt` — allocator alignment and false sharing
- `skills/kernel/kernel-internals` — SLUB/buddy kernel allocators
© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills