Understanding Linux Memory Allocation: Buddy, Slab, and Slub Explained
Linux’s memory allocation mechanisms—Buddy for main memory and Slab/Slub for CPU cache—aim to maximize memory utilization, minimize fragmentation, and boost allocation efficiency, with detailed explanations of their structures, operation steps, and how to inspect them via /proc interfaces.
Linux Memory Allocation Algorithms
Linux memory allocation algorithms manage system memory with three key goals: maximize utilization, avoid fragmentation, and improve allocation efficiency.
Maximize utilization of memory resources
Avoid memory fragmentation
Increase allocation efficiency
The kernel implements two major types of allocation algorithms:
Buddy allocator for main memory
Slab/Slub allocator for CPU cache
Note: the malloc() interface provided by glibc uses its own allocator and is not covered here.
Buddy Allocation Algorithm
The Buddy system aims to minimize fragmentation when managing physical memory pages.
Linux implements 11 free lists, each representing blocks of size 2^n * PageSize (n = 0‑10), i.e., 4 KB, 8 KB, …, 4 MB for a default 4 KB page size.
When allocating a block of size size, Buddy searches for a block ≥ size and follows these steps:
If a block exactly equal to size exists, allocate it directly.
If a larger block exists, split it and place the remainder into a smaller free list.
If no suitable block exists, combine smaller blocks to form a sufficient one, possibly splitting the result and returning the remainder to a smaller list.
When freeing memory, Buddy checks neighboring pages to see if they can be merged into a larger buddy block.
Kernel command to view Buddy allocation status:
$ cat /proc/buddyinfo
Node 0, zone DMA 1 0 0 0 2 1 1 0 1 1 3
Node 0, zone DMA32 189 209 119 80 38 17 11 1 1 2 627
Node 0, zone Normal 1298 1768 1859 661 743 461 275 133 68 61 2752Slab Allocation Algorithm
Slab allocates kernel objects using an object cache, suitable for many small objects that would be inefficient with Buddy.
It maintains a structure of “2‑level list + 1‑level page table”.
Creates a cache_chain list of kmem_cache entries of various object sizes (e.g., 32 B, 128 B, 32 KB).
Each kmem_cache contains three slab lists: slabs_full, slabs_partial, and slabs_empty/free.
Each slab can serve multiple objects, with a page table mapping slabs to pages.
Slabs move between these lists as they become fully allocated, partially allocated, or empty.
Allocation flow:
If slabs_partial has free space, allocate to objects; when full, move slab to slabs_full.
If slabs_partial is empty, check slabs_empty.
If slabs_empty has space, allocate and move slab to slabs_partial.
If no empty slabs, request a page from Buddy, create a new empty slab, then allocate.
View Slab information via:
$ cat /proc/slabinfo
slabinfo - version: 2.1
# name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
isofs_inode_cache 50 50 640 25 4 : tunables 0 0 0 : slabdata 2 2 0
kvm_async_pf 0 0 136 30 1 : tunables 0 0 0 : slabdata 0 0 0
kvm_vcpu 0 0 14976 2 8 : tunables 0 0 0 : slabdata 0 0 0
xfs_dqtrx 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0
xfs_dquot 0 0 488 33 4 : tunables 0 0 0 : slabdata 0 0 0
xfs_ili 40296 40296 168 24 1 : tunables 0 0 0 : slabdata 1679 1679 0
xfs_inode 41591 41616 960 34 8 : tunables 0 0 0 : slabdata 1224 1224 0
xfs_efd_item 1053 1053 416 39 4 : tunables 0 0 0 : slabdata 27 27 0Slub Allocation Algorithm
Slub addresses Slab’s shortcomings on NUMA and multi‑core systems by giving each CPU core a local kmem_cache_cpu and simplifying slab lists.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
