Memory Bookkeeping, Free/Used Lists & Buddy Allocator

Tanenbaum Chapter 3: The Purpose of Allocation Lists, Bitmaps, Linked Lists of Segments, and Binary Buddy Systems.

1. Historical Foundations & The Purpose of Allocation Lists

What are Allocation Lists? When an operating system kernel manages physical memory, it cannot simply guess which bytes of RAM are available. It must maintain rigorous bookkeeping structures known as allocation lists. These consist of Free Lists (grouping unallocated blocks or holes) and Used Lists/Trackers (recording active process ownership, starting addresses, and block lengths).

Why are they used? Without allocation lists, the kernel would be forced to perform exhaustive linear scans across every byte of raw hardware RAM every time a program requests or releases memory. Allocation lists enable structured, rapid metadata lookups, prevent memory corruption, and allow efficient coalescing of adjacent free blocks to mitigate external fragmentation.

A Brief History: Early computer systems in the 1950s and early 1960s used primitive bitmaps and sequential linked lists of variable-length holes. To solve the persistent problem of external fragmentation and slow search times, the Binary Buddy System was introduced by Harry M. Markowitz in 1963, refined by Kenneth C. Knowlton in 1965, and standardized across computer science by Donald Knuth.

Free Lists (Availability)

Group unallocated blocks by power-of-two sizes (`free_area[0..MAX_ORDER]`). Enables instant O(1) pop operations when allocating memory.

Used Trackers (Ownership)

Record active allocations and metadata. When a process frees a pointer, the kernel inspects this tracker to know the exact block boundaries for buddy coalescing.

Harry Markowitz

Harry M. Markowitz

Formulated the binary buddy allocation algorithm (1963). Nobel laureate.

Image source: Zicklin News, Baruch College (Copyrighted).
View Wikipedia →
Ken Knowlton

Kenneth C. Knowlton

Refined buddy allocation structures at Bell Labs (1965) for Lisp architectures.

Image: Wikimedia Commons (CC BY 3.0, cropped).
View Wikipedia →
Donald Knuth

Donald E. Knuth

Rigorously analyzed and popularized buddy systems in The Art of Computer Programming.

Image: Wikimedia Commons (CC BY 3.0, cropped).
View Wikipedia →
2. Tanenbaum's Method 1: Bookkeeping with Bitmaps

Memory is partitioned into fixed allocation units (e.g., 4 KB blocks). Each unit corresponds to a single bit in a bitmap: 0 if free, and 1 if allocated to a process.

Figure: Memory Allocation Tracked via Bitmaps Memory Units (4 KB each): 1 1 0 0 1 1 0 Bitmap Array: 1 1 0 0 1 1 0
3. Tanenbaum's Method 2: Bookkeeping with Linked Lists of Segments

The operating system maintains a linked list where each node indicates whether a region is a Process (P) or a Hole (H), its starting address, and its length.

Figure: Tanenbaum's Linked List of Segments (Holes & Processes) Process A (Addr 0, Len 140) Hole (Addr 140, 90) Process B (Addr 230, Len 200) Hole (Addr 430, 210) Linked List Nodes: [ P | Start: 0 | Len: 140 ] → points to next [ H | Start: 140 | Len: 90 ] → points to next [ P | Start: 230 | Len: 200 ] → points to next [ H | Start: 430 | Len: 210 ] → NULL
4. Classical Placement Strategies (First Fit, Best Fit, Worst Fit, Next Fit)

When allocating memory from a linked list of holes, the kernel uses placement algorithms to decide which hole to assign:

What is a PFN (Page Frame Number)?
Physical DRAM is partitioned by hardware into fixed-sized slots called page frames (commonly 4096 bytes or 212). The PFN is simply the sequential integer index of that frame:
PFN =
Physical Address 4096
= Physical Address >> 12
Physical address 0x0000 is PFN 0, 0x1000 is PFN 1, 0x2000 is PFN 2, and so on. The buddy system performs all pairing directly on this integer index.
Step 1 of 8 State: Idle
1. Initial Setup: The Single Max Block
Physical Memory Range (PFN 0 to 15) 16 Pages × 4 KB = 64 KB Total Pool
PFN 0 (0x0000) PFN 4 (0x4000) PFN 8 (0x8000) PFN 12 (0xC000) PFN 15 (0xF000)
Kernel Free List Array (free_area[0..4])
Active Allocations (Used Tracker)
No active allocations (Used list empty).
Kernel Memory Allocator Trace