How Linux Slab Allocator Manages Object Caching
The Linux slab allocator is a memory management mechanism designed to optimize kernel memory allocation by retaining pre-allocated, initialized object instances in dedicated caches. Rather than repeatedly allocating and freeing memory pages through the lower-level buddy allocator—which introduces latency and internal fragmentation—the slab allocator maintains pools of commonly requested kernel structures, such as inodes, process descriptors, and network buffers. This overview explores the architectural structure of the slab allocator, the life cycle of cached objects, and the operational mechanics that allow Linux to achieve high-performance memory utilization.
The Purpose of Object Caching
In an operating system kernel, specific data structures are created, used, and destroyed millions of times during system operation. Creating a complex kernel object typically involves two expensive operations: allocating memory space and initializing its member fields (such as locks, list pointers, and reference counters).
The buddy allocator, which is Linux's primary page allocation system, operates on chunks of memory consisting of whole pages (typically 4 KB or larger). Using the buddy system to allocate small objects—such as a 128-byte data structure—causes severe internal fragmentation and excessive page management overhead. The slab allocator sits between the buddy allocator and kernel requests, slicing full pages into fixed-size slots and keeping the underlying objects in a semi-constructed state to eliminate the need to re-initialize them on every allocation.
The Slab Allocator Hierarchy
The slab caching architecture operates across three main structural tiers:
- Caches (
kmem_cache): Each specific type of kernel object has its own dedicated cache (for example,task_struct,mm_struct, ordentry). There are also generic caches used bykmallocto satisfy arbitrary byte-size requests. A cache tracks allocation metrics, object sizes, constructors, and pointers to slab lists. - Slabs: A slab consists of one or more physically contiguous memory pages obtained from the buddy system. These pages are divided into an array of equal-sized memory slots corresponding to the object type held by the cache.
- Objects: These are the individual data structures residing inside a slab. They represent the actual memory addresses returned to kernel subsystems during an allocation call.
Slab States and Tracking
To manage memory availability efficiently, slabs within a cache are organized into three primary states:
- Full: Every object slot within the slab is currently allocated and in use.
- Partial: The slab contains both allocated objects and available, free objects.
- Empty: All object slots in the slab are free, and no active references exist.
When a subsystem requests an object via
kmem_cache_alloc(), the allocator searches the partial list
first to satisfy the request without requesting new memory. If no
partial slab exists, it uses an empty slab. If no empty slabs are
available, the allocator queries the buddy system to allocate fresh
physical pages and creates a new slab.
Allocation and Deallocation Mechanics
The primary optimization of the slab allocator lies in how it handles the lifecycle of an object:
- Allocation (
kmem_cache_alloc): When invoked, the allocator locates the first available object slot using an internal free-list pointer. Because the object is already associated with its cache metadata, minimal setup is required, and the pointer to the object is returned immediately. - Deallocation (
kmem_cache_free): When the kernel releases an object, it is not returned to the system's global memory pool. Instead, the object is simply linked back into the free list of its parent slab. The internal invariants of the structure (like list heads and spinlocks) remain intact, bypassing the need to reconstruct the object when it is requested again.
If freeing an object causes a slab to transition from full to partial, the slab is moved to the partial list. If all objects within a slab become free, the slab moves to the empty list.
Memory Reclamation
To prevent kernel caches from consuming excessive amounts of RAM, the slab allocator includes a reclamation interface integrated with the kernel's memory management subsystem. During periods of low memory pressure, empty slabs remain intact to handle future allocation bursts. Under significant memory pressure, kernel shrinkers trigger the release of empty slabs, returning the underlying physical pages back to the buddy allocator for use by user-space applications or other kernel components. Modern implementations (such as the default SLUB allocator) refine this model by using per-CPU slab queues to eliminate lock contention on multiprocessor systems.