Understanding Linux Kernel Memory Compression and the Zsmalloc Allocator
This article explains the fragmentation problems of the Linux slab allocator, introduces the zsmalloc memory allocator and its requirements, surveys mainstream kernel memory‑compression techniques such as zSwap, zRAM and zCache, and details related allocators like Zbud and Z3fold with example source code.
In the Linux kernel, the slab allocator can cause internal fragmentation when objects do not perfectly fill a page, especially on low‑memory devices where allocating multiple physically contiguous pages becomes nearly impossible; a new allocator that only requires virtual contiguity, similar to vmalloc, is needed.
1. Mainstream Memory Compression Techniques
1.1 zSwap
zSwap compresses inactive pages and stores the compressed data on disk instead of a traditional swap partition, using an LRU policy and adaptive optimization to reduce memory pressure.
1.2 zRAM
zRAM (formerly compcache) creates a compressed block device in RAM, paging to it before resorting to disk swap, which improves performance on devices with limited physical memory and reduces I/O wear on flash storage.
1.3 zCache
zCache accelerates file‑system reads by caching compressed pages in memory via the frontswap and cleancache components, though it must be manually enabled and has limitations such as incompatibility with zsmalloc.
2. Memory‑Compression Allocators
2.1 Zsmalloc
Zsmalloc is a kernel allocator designed for virtual machines (e.g., KVM) that stores multiple same‑size objects in a non‑physically‑contiguous composite page (zspage), improving memory utilization. It requires explicit mapping before use and must be accessed in atomic context.
2.2 Zbud
Zbud is the underlying data structure for Zsmalloc; it splits a contiguous physical page into fixed‑size blocks managed by a tree, reducing external fragmentation and providing dynamic allocation suitable for high‑concurrency workloads.
2.3 Z3fold
Z3fold compresses rarely used or duplicate pages using the LZ77 algorithm, stores them in dedicated compressed pages, and manages them with hash tables to avoid external fragmentation, offering configurable performance trade‑offs.
3. Zsmalloc Allocator Source Code
The following pseudo‑code illustrates the core functions of the Zsmalloc allocator, including initialization, allocation, reallocation, freeing, and statistics collection.
// Initialize zsmalloc allocator
void zsm_init(size_t size) {
// Initialize global allocator state
}
// Allocate memory
void *zsm_alloc(size_t size) {
// Allocate from global buffer and return pointer
}
// Reallocate memory
void *zsm_realloc(void *ptr, size_t size) {
// If possible, resize in place; otherwise allocate new block and free old
}
// Free memory
void zsm_free(void *ptr) {
// Mark block as reusable without actually freeing
}
// Analyze memory usage
void zsm_stats(size_t *allocated, size_t *highwater) {
// Return current and peak allocation amounts
}This example demonstrates the basic API; the real implementation includes complex concurrency control, buffer management, and integration with the kernel's memory subsystem.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
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.