the slab allocator (SLUB)
/ slab /
Suppose your kitchen constantly needs identical, pre-set tables: tablecloth on, cutlery laid out, glasses placed. Tearing a table down and setting it up again from scratch every single time is wasteful. A smarter scheme: keep a stack of tables already set up, hand one out when needed, and when it comes back, do not strip it bare — just leave it set, ready to go again. The slab allocator does this for kernel objects: it allocates fixed-size objects from caches and remembers their initialized state so reuse skips the setup cost.
Concretely, a slab allocator (invented by Jeff Bonwick for Solaris, and the model for Linux's kernel allocators) is built from two ideas. First, an object cache: for each kind of frequently-used object — say struct inode, or struct task_struct — there is a dedicated cache that hands out objects of exactly that size. Internally a cache owns one or more slabs, where a slab is a contiguous chunk (often a page or a few pages) sliced into many same-size object slots, managed pool-style. Second, constructor reuse / object caching: when an object is freed back to the cache, the allocator does not destroy it; it can keep the object in a partly-initialized state so that the next allocation skips re-running the constructor for the parts that did not change (the classic example is a lock or list-head inside the object that is already initialized). This makes both the allocation and the initialization of common kernel objects very cheap, and it keeps same-type objects packed together for good cache behavior.
In Linux the original SLAB was largely replaced by SLUB, a simpler, lower-overhead reimplementation of the same slab concept that is the default today (a low-memory variant SLOB also existed and has since been removed). The honest framing: slab allocation is the specialised, per-object-type layer used heavily inside the kernel; it sits on top of the page-granularity buddy allocator, which hands the slab system its raw pages. So slabs solve fast, fragmentation-free allocation of many small fixed-size kernel objects, while the buddy system solves coarse page-sized allocation underneath.
/* Linux kernel: a cache of one object type, reusing initialized state */ struct kmem_cache *c = kmem_cache_create("my_inode", sizeof(struct my_inode), 0, 0, my_ctor); /* ctor runs once per slot */ struct my_inode *p = kmem_cache_alloc(c, GFP_KERNEL); /* ... use p ... the embedded lock was pre-initialized by ctor */ kmem_cache_free(c, p); /* returns to cache, not torn down */
A slab cache hands out same-type objects and reuses their initialized state, so reuse skips re-construction.
Slab is a kernel-side specialisation, not a drop-in replacement for malloc(). It assumes you allocate many objects of one known type, and it relies on the page-level buddy allocator beneath it for its backing memory.