Long Article 103: Memory Management – Kernel: In-Depth Slab Allocator Design — Compared with Linux
“The Buddy system excels at allocating large chunks, but what about the kernel’s frequent 32-byte task_struct allocations? This article dives into the Slab allocator’s design philosophy, compares Linux’s three implementations (SLAB/SLUB/SLOB), and builds a high-performance, low-fragmentation industrial-grade Slab system.”
The Problem with Small Object Allocation
In an OS kernel, small object allocation is extremely frequent:
- Process creation: task_struct (~1.5KB)
- File operations: file (~200 bytes), dentry (~192 bytes)
- Network stack: sk_buff (~256 bytes)
- VFS layer: inode (~600 bytes)
If using Buddy system directly:
- Internal fragmentation 75%+: 4KB page for 200 bytes
- Huge initialization overhead: memset clears entire page each time
- Poor cache locality: objects scattered across pages
The Slab allocator solves these problems with object caching + free list:
- Zero initialization overhead: object reuse, constructor called as needed
- Zero internal fragmentation: precise object size allocation
- High cache hit rate: same-type objects stored compactly
Slab Three-Level Architecture
- Slab: One or more contiguous physical pages, divided into fixed-size objects
- Cache: Manages the Slab pool for same-type objects (e.g., task_cache, file_cache)
- Object reuse: freed objects returned to free list, not to Buddy
Key design decisions:
- Embedded free pointers: pointer stored at start of object memory — zero extra overhead
- Deferred constructor calls: ctor called only on first allocation, not on reuse
- On-demand slab creation: new pages allocated from Buddy only when no free objects available
Comments