Most of the current servers run on Linux, so as a programmer, it's essential to have a basic understanding of how the system operates. When it comes to memory, there are several key concepts you should be familiar with: address mapping, memory management, and page fault handling. Let’s dive into some fundamental knowledge about how memory works in Linux.
In a process, memory is typically divided into two main regions: user mode and kernel mode. The classic distribution looks like this:

Switching from user mode to kernel mode usually happens through system calls or interrupts. User mode memory is further segmented for different purposes, such as code, stack, heap, and data segments.

The kernel mode isn't used indiscriminately; it's structured into specific areas for managing hardware, processes, and other critical functions.

Now, let's take a closer look at how memory is actually managed inside Linux.
### Address Mapping
Linux uses a three-step process for address mapping: logical address → linear address → physical address. The physical address is the actual location in memory, while the linear and logical addresses represent virtual addresses that are translated by the MMU (Memory Management Unit). This translation involves registers like CR0 and CR3.

In Linux, the logical address is often equivalent to the linear address, which simplifies things compared to other operating systems that use more complex addressing schemes.
### Memory Management
When the system boots, it first detects the available memory. Initially, it uses a simple method called bootmem, which acts like a bitmap to track free memory blocks. However, bootmem is not very efficient for large-scale allocations.
To improve efficiency, Linux uses the **buddy system**, which manages memory in powers of two. For example, if you need 3 pages, the system will allocate a block of 4 pages, then return the extra one back to the pool. This helps reduce fragmentation.

When releasing memory, the buddy system reverses the process. It checks for adjacent free blocks and merges them when possible. The code below shows how the buddy index is calculated:
```c
static inline unsigned long __find_buddy_index(unsigned long page_idx, unsigned int order)
{
return page_idx ^ (1 << order);
}
```
This ensures that only compatible blocks are merged, helping to prevent fragmentation.
For small objects, Linux uses the **slab allocator**. Instead of allocating full pages for each object, slab pre-allocates memory in chunks and reuses them. This is especially useful for frequently allocated objects like file descriptors or network packets.

However, slab has some limitations, especially in multi-core or NUMA environments. To address these issues, the **slub** allocator was introduced. It reduces overhead by using per-CPU caches and simplifying management structures. For smaller embedded systems, **slob** is used instead.
When dealing with large contiguous memory blocks, the **vmalloc** function comes into play. It allows the system to allocate non-contiguous physical memory and map it as a single virtual block, similar to assembling pieces of a puzzle.

In addition to direct mapping, Linux provides the `kmap` function to assign a linear address to a specific page when needed.
### Process Memory Segments
Each process has its own virtual address space, consisting of multiple segments like code, data, heap, and stack. These are managed separately by the kernel.

When a program calls `malloc`, it doesn’t immediately allocate physical memory. Instead, it reserves virtual memory and allocates physical memory only when it’s actually accessed. This is known as **Copy-on-Write (COW)**, which helps optimize resource usage.
### Page Faults
Page faults occur when a process tries to access a virtual memory region that hasn’t been mapped to a physical page yet. The CPU raises an exception, and the kernel handles it by either allocating a new page or swapping it in from disk.

The kernel can also swap out less-used pages to disk to free up memory. You can check swap usage with commands like `free` or `top`.

If a memory region is mapped via `mmap`, accessing it can also trigger a page fault. Understanding these mechanisms is crucial for writing efficient and stable applications on Linux.
Jilin Nengxing Electrical Equipment Co. Ltd. , https://www.nengxingelectric.com