Chapter 9 - Memory Management
This document summarizes the key concepts from Chapter 9: Memory Management in Linux System Programming, 2nd Edition by Robert Love*. It provides an overview of how memory is managed in user space, the role of the kernel, common functions for allocation and manipulation, and techniques to optimize and debug memory usage.
Overview
Memory management in Linux is a fundamental component of system programming. It involves allocating, using, and releasing memory safely and efficiently. Proper memory handling avoids fragmentation, memory leaks, and undefined behavior.
The chapter focuses on:
- How user-space processes interact with the kernel for memory allocation.
- The process memory layout and its components.
- Allocation strategies in both heap and stack.
- Advanced techniques like memory mapping and page locking.
- Debugging tools for memory issues.
Key Topics
1. Memory Layout of a Process
Every Linux process has a well-defined memory layout, divided into segments:
- Text Segment – Holds the compiled machine code of the program. Typically marked read-only and executable to prevent accidental modification.
- Data Segment – Contains initialized global and static variables.
- BSS Segment – Holds uninitialized global and static variables, which the kernel initializes to zero at program start.
- Heap – Dynamic memory allocated at runtime using
malloc,calloc, orrealloc. Grows upward as needed. - Stack – Stores function call frames, local variables, and return addresses. Grows downward on most architectures.
- Memory Mappings – Regions created with
mmap(), commonly used for shared libraries and large allocations.
Understanding this layout is essential for writing efficient, low-level programs and debugging memory-related issues.
2. Dynamic Memory Allocation
Dynamic allocation functions allow flexible use of memory at runtime:
- malloc(size_t size) – Allocates a memory block of the given size without initialization.
- calloc(size_t nmemb, size_t size) – Allocates memory for an array of
nmembelements, initializing all bytes to zero. - realloc(void *ptr, size_t size) – Resizes an existing memory block, preserving its contents up to the smaller of the old and new sizes.
- free(void *ptr) – Releases previously allocated memory.
Common pitfalls
- Memory leaks – Occur when allocated memory is not freed before losing all references to it.
- Double free – Freeing the same memory block twice, which causes undefined behavior.
- Use-after-free – Accessing a memory block after it has been freed, leading to crashes or data corruption.
3. brk and sbrk
Historically, brk() and sbrk() were used to manipulate the program break, which defines the end of the process’s data segment.
brk()sets the end of the data segment.sbrk()increments (or decrements) the break value.
Modern applications rarely use these functions directly; instead, malloc and related functions manage them internally. These interfaces are considered low-level and non-portable.
4. Memory Mapping with mmap
mmap() maps files or anonymous memory into the process’s address space.
Advantages
- Eliminates the need for additional copies when reading files.
- Enables efficient handling of large files and inter-process communication.
Typical use cases
- Memory-mapped file I/O.
- Shared memory regions for IPC.
- Allocating large anonymous memory regions.
To release mappings, use munmap(). Unlike malloc, which uses the heap, mmap provides greater flexibility for aligning memory and mapping hardware devices.
5. Advanced Memory Techniques
Several specialized APIs provide advanced control over memory:
- mprotect() – Changes access permissions (read, write, execute) for a memory region.
- shm_open() / shm_unlink() – Creates and removes POSIX shared memory objects for inter-process communication.
- posix_memalign() – Allocates memory aligned to a specific boundary, useful for SIMD operations or page-aligned buffers.
These functions are essential in performance-sensitive and real-time systems.
6. Debugging Memory Issues
The GNU C Library provides several functions to inspect and analyze memory usage at runtime:
- mallinfo()
Returns astruct mallinfowith statistics about memory allocation, such as total allocated space, number of free blocks, and fragmentation levels. - *malloc_usable_size(void ptr)
Returns the actual usable size of an allocated block. This value may be larger than the size requested frommalloc()due to alignment or internal overhead. - malloc_trim(size_t pad)
Attempts to return unused memory from the heap back to the operating system, retainingpadbytes for future allocations. Useful for long-running processes to reduce memory footprint. - malloc_stats()
Prints detailed statistics about memory allocation directly tostderr.
This includes information about the heap, allocated blocks, and free space.
Notes
- These functions are GNU-specific and may not be portable across different C libraries or UNIX-like systems.
- They are primarily intended for debugging and profiling, not for production code paths that require high performance.
- Use them to analyze fragmentation patterns, memory usage trends, and allocator behavior during development or testing.
7. Stack-Based Allocation
Stack allocation can be an efficient alternative for temporary buffers:
- alloca(size_t size) – Allocates memory on the calling function’s stack frame. The allocated memory is automatically released when the function returns, so
free()is unnecessary.
Advantages
- Extremely fast allocation and deallocation.
- Ideal for short-lived buffers with known size limits.
Limitations
- Memory is valid only within the function scope. Returning a pointer to stack memory results in undefined behavior.
- Excessive allocation can lead to stack overflow and program crashes.
alloca()is not part of the ISO C standard, but it is available as a POSIX or compiler-specific extension.
Example:
void example(size_t size) {
char *buffer = alloca(size);
// Use buffer safely within this function only
}
8. Manipulating Memory
C provides several functions for low-level memory manipulation:
-
memset(void *s, int c, size_t n)
Fills a block of memory with a given byte value.
Example:memset(buffer, 0, sizeof(buffer)); // Zero out buffer -
memcpy(void *dest, const void *src, size_t n)
Copiesnbytes fromsrctodest. Behavior is undefined if regions overlap. -
memmove(void *dest, const void *src, size_t n)
Likememcpy, but handles overlapping memory correctly. -
memcmp(const void *s1, const void *s2, size_t n)
Compares two memory regions byte by byte, returning:< 0ifs1<s20if equal> 0ifs1>s2
-
memchr(const void *s, int c, size_t n) Scans the n bytes of memory pointed at by s for the character c, which is interpreted as an unsigned char
-
memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) Returns a pointer to the first occurrence of the subblock needle, of length needlelen bytes, within the block of memory haystack, of length haystacklen bytes. If the function does not find needle in haystack, it returns NULL.
This function is a GNU extension
These functions do not perform type checking or add null terminators, making them ideal for raw data operations but requiring caution to avoid buffer overruns.
9. Locking Memory
Linux provides mechanisms to lock memory pages into RAM:
- mlock() – Locks a specific memory range, preventing it from being swapped out.
- mlockall() – Locks all pages mapped by the calling process.
Use cases
- Real-time systems that must avoid page faults.
- Applications handling sensitive data such as encryption keys, ensuring they never hit disk.
After use, memory should be unlocked with munlock() or munlockall().
Key Takeaways
- Understanding the process memory layout is critical for writing efficient and safe programs.
- Dynamic allocation with
mallocand its variants is powerful but requires careful management to avoid leaks and corruption. - Use
mmapfor large or shared allocations andallocafor small, temporary buffers. - Memory manipulation functions provide high performance but require strict attention to bounds and alignment.
References
- Linux System Programming, 2nd Edition – Robert Love, O’Reilly Media.
man malloc,man mmap,man alloca,man mprotect,man mlock.