SoFunction
Updated on 2025-04-05

How to allocate memory in Linux

introduction

In Linux operating systems, memory management is a core component in ensuring system performance and stability. For developers, understanding the memory allocation mechanism not only helps write more efficient programs, but also helps them better debug and optimize applications; for system administrators, mastering knowledge in this field can improve resource utilization and ensure the continuity and reliability of services. The Linux kernel manages and optimizes limited physical memory (RAM) through complex algorithms and strategies. It is like a clever butler, always working silently behind the scenes, ensuring that every task can get enough memory space and minimize waste.

Imagine if a busy train station does not have a reasonable dispatch system, passengers may encounter problems such as long waiting time and chaotic boarding order. Similarly, without good memory management in computer systems, applications will find it difficult to respond to user requests quickly, and may even cause the entire system to crash. Therefore, in-depth learning of Linux memory allocation is like building an efficient transportation network for this virtual world, allowing data to flow smoothly and unimpededly.

Physical and virtual memory

Physical memory refers to RAM chips installed on the computer motherboard, which are directly connected to the CPU to provide extremely fast data access. However, due to cost and technical limitations, the physical memory of any machine is limited. To overcome this limitation, modern operating systems have introduced the concept of virtual memory, which allows each process to have its own independent and vast address space, as if each car has an unlimited garage.

Linux uses a paging mechanism to implement mapping from virtual addresses to physical addresses, where page tables play the role of maps, guiding each addressing operation. Whenever a program needs to read or write to a memory location, the CPU will first look for the page table to determine the physical address corresponding to the location; if it cannot be found, a page-missing interrupt will be triggered, and the operating system will be responsible for loading the required data blocks - what we call the page box - into the actual available RAM. This design not only simplifies the programming model, but also increases the flexibility of the system, allowing programs with larger amounts of memory than actual physical.

Memory allocation policy

When it comes to specific memory allocation, Linux adopts a variety of strategies to deal with needs in different scenarios. The most famous of these are the buddy system and the slab allocator.

A partner system is a dynamic memory allocation method that divides all free memory into blocks of varying sizes but always at power of 2. When a new memory request arrives, the system will try to find the smallest block closest to the request size for allocation. If a block of the right size cannot be found, continue to split the larger block until the requirements are met. Conversely, when memory is freed, adjacent small chunks are merged into larger chunks for subsequent use. This method effectively reduces external fragmentation and improves memory utilization efficiency.

On the other hand, slab allocators are mainly used for object-level memory management, especially for small objects that are frequently created and destroyed. It pre-divides multiple fixed-size cache areas (called slabs), each containing several object instances of the same type. When an application requests a specific type of object, the slab allocator can directly allocate an initialized instance from the corresponding cache area, greatly speeding up the allocation. At the same time, it also supports instant recycling of objects, further optimizing memory usage.

# Use the vmstat command to view memory allocationvmstat -s | grep "used memory"

Process memory layout

Every Linux process has its own unique memory layout, just like every family has its own room arrangement. A typical memory layout includes the following main parts:

  • Code segment: Store binary instructions for the program, this part of the content is usually read-only.
  • Data segment: Used to store global variables and static variables, divided into initialized data (such as preset values) and uninitialized data (such as bss segment in C).
  • Stack area: Dynamically allocated memory area, programmers can usemalloc()calloc()The functions of the etc. apply for additional space here.
  • Stack area: Used to save local variables and return addresses when calling a function, which grows as the function call stack grows.

In addition, there are mapping areas after shared libraries are loaded and shared memory used in multithreaded programming. For example, when we start an application based on the GTK graphical interface, it loads such a shared library, thus avoiding repeated loading of the same library files and saving valuable memory resources.

#include <>

int main() {
    // Dynamically allocate an array of 10 integers    int *array = (int *)malloc(10 * sizeof(int));
    if (array == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }
    
    // Release the memory after use    free(array);
    return 0;
}

Memory management tools and technologies

Linux provides a wealth of command line tools and technologies to help users monitor and optimize memory performance. For example, the top command can display the memory information occupied by each process in real time; the free command displays the overall memory usage of the system; in addition to calculating memory, vmstat can also observe disk I/O and other key indicators. These tools are like stethoscopes and thermometers in doctors’ hands, providing an important basis for us to diagnose problems.

In addition, there are some advanced features worth mentioning. For example, the mmap() function allows us to map files or devices to the process's address space, thereby simplifying the operation of large files; the POSIX message queue provides a cross-process communication method, which can pass structured packets between different processes. These are the concrete manifestations of Linux's powerful memory management capabilities.

# Use the top command to view the current active process and its memory consumptiontop -o %MEM

Page replacement algorithm

Although Linux does its best to optimize memory allocation, there are still problems with insufficient memory in some cases. At this time, the kernel needs to make a difficult choice: which pages should be moved out of physical memory? The page permutation algorithm is the key to solving this problem.

The Least-Used (LRU) algorithm believes that pages that have not been visited in the recent period are likely to not be used in the future, so they are preferred to swap them out. The clock algorithm is more flexible. It scans the page list in a certain order. Once it is found that a page has exceeded the set time threshold since its last visit, it will be used as a candidate. These two algorithms have their own advantages and disadvantages. The former is relatively simple and intuitive, while the latter can predict future access modes to a certain extent to achieve better results.

# Adjust swappiness parameters to affect page replacement behaviorsudo sysctl =10

Overuse of memory and swap space

When physical memory is insufficient to support the needs of all active processes, Linux enables swap space as a "backup force". Swap partitions or files act as additional virtual memory, allowing temporarily moving inactive pages to the hard drive, making room for more important tasks. However, swapin/swapout operations involve a large amount of disk I/O, which is much lower than direct access to RAM, so over-reliance on swap space will lead to system performance degradation.

Adjusting the /proc/sys/vm/swappiness parameter can help us control this trade-off. Lower values ​​mean minimizing the use of swap space and maintaining a higher response speed; higher values ​​tend to use swap space more actively in exchange for a larger total amount of available memory. Choosing the appropriate configuration according to the specific application scenario is an issue that every system administrator must consider.

# Check the current swappiness settingscat /proc/sys/vm/swappiness

Memory leak detection and prevention

Last but not least, memory leaks are a long-standing problem for developers. It occurs when the program fails to properly free memory that is no longer in use, causing more and more memory to be invalidated over time. To avoid this, we should follow some best practices, such as timely releasing dynamically allocated resources to avoid circular references that cause the garbage collector to recover objects.

Fortunately, the Linux community has prepared us with excellent tools like Valgrind. It can automatically detect memory errors during program operation, including but not limited to out-of-bounds access, dangling pointers, and memory leaks. By combining these tools and good coding habits, we can effectively improve the quality of the software and ensure the stable operation of the service.

# Use Valgrind to detect memory leaksvalgrind --leak-check=full ./your_program

This is the article about the methods and steps of Linux memory allocation. For more related Linux memory allocation content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!