Home >System Tutorial >LINUX >Master Linux memory management and improve your program performance!
Linux, as an operating system widely used in servers and embedded devices, occupies an increasing market share. In these scenarios, memory management is crucial because it directly affects the performance and stability of the system, especially for programmers. For programmers who want to develop high-performance applications on the Linux platform, proficiency in Linux memory management is a must. Today we will introduce an article that every programmer should read: Linux memory management.
Need to know about the memory part:
Let’s first look at some basic knowledge. From the perspective of a process, memory is divided into two parts: kernel mode and user mode. The classic ratio is as follows:
From user mode to kernel mode is generally achieved through system calls and interrupts. User-mode memory is divided into different areas for different purposes:
Of course the kernel state will not be used indiscriminately, so it is divided as follows:
Let’s take a closer look at how these memories are managed.
address
The mapping process of addresses within Linux is logical address –> linear address –> physical address. Physical address is the simplest: a digital signal transmitted in the address bus, while linear address and logical address represent a conversion. Rules, linear address rules are as follows:
This part is completed by the MMU, which involves the main registers CR0 and CR3. What appears in the machine instructions is the logical address, and the logical address rules are as follows:
The logical address in Linux is equal to the linear address, which means that Inter makes things very complicated for compatibility, and Linux simplifies it and is lazy.
Memory management method
When the system boots, it will detect the size and condition of the memory. Before establishing complex structures, it is necessary to manage these memories in a simple way. This is bootmem, which is simply a bitmap, but there are some Optimization ideas.
No matter how optimized bootmem is, the efficiency is not high. After all, it has to be traversed when allocating memory. The buddy system can just solve this problem: internally save some free memory fragments with a power of 2 size. If you want to allocate 3page, go to the 4page list and pick one, allocate 3 and put the remaining 1 back. The process of memory release is just the reverse process. Use a picture to represent it:
You can see that 0, 4, 5, 6, and 7 are all in use. So, when 1 and 2 are released, will they be merged?
static inline unsigned long __find_buddy_index(unsigned long page_idx, unsigned int order) { return page_idx ^ (1
As you can see from the above code, 0 and 1 are buddies, and 2 and 3 are buddies. Although 1 and 2 are adjacent, they are not. Memory fragmentation is the enemy of system operation. The buddy system mechanism can prevent fragmentation to a certain extent. In addition, we can obtain the number of free pages in each order through cat /proc/buddyinfo.
Every time the partner system allocates memory, it is in units of pages (4KB), but most of the data structures used when the system is running are very small. It is obviously not cost-effective to allocate 4KB to a small object. . Use slab in Linux to solve the allocation of small objects:
When running, slab "wholesale" some memory to buddy, processes and cuts it into pieces and "sells" it out in bulk. With the widespread application of large-scale multi-processor systems and NUMA systems, slab has finally exposed its shortcomings:
In order to solve these problems, experts developed slub: transform the page structure to reduce the overhead of the slab management structure, each CPU has a locally active slab (kmem_cache_cpu), etc. For small embedded systems, there is a slab simulation layer slob, which has more advantages in such systems.
小内存的问题算是解决了,但还有一个大内存的问题:用伙伴系统分配10 x 4KB的数据时,会去16 x 4KB的空闲列表里面去找(这样得到的物理内存是连续的),但很有可能系统里面有内存,但是伙伴系统分配不出来,因为他们被分割成小的片段。那么,vmalloc就是要用这些碎片来拼凑出一个大内存,相当于收集一些“边角料”,组装成一个成品后“出售”:
之前的内存都是直接映射的,第一次感觉到页式管理的存在:D 另外对于高端内存,提供了kmap方法为page分配一个线性地址。
进程由不同长度的段组成:代码段、动态库的代码、全局变量和动态产生数据的堆、栈等,在Linux中为每个进程管理了一套虚拟地址空间:
在我们写代码malloc完以后,并没有马上占用那么大的物理内存,而仅仅是维护上面的虚拟地址空间而已,只有在真正需要的时候才分配物理内存,这就是COW(COPY-ON-WRITE:写时复制)技术,而物理分配的过程就是最复杂的缺页异常处理环节了,下面来看!
缺页异常
在实际需要某个虚拟内存区域的数据之前,和物理内存之间的映射关系不会建立。如果进程访问的虚拟地址空间部分尚未与页帧关联,处理器自动引发一个缺页异常。在内核处理缺页异常时可以拿到的信息如下:
处理的流程如下:
发生缺页异常的时候,可能因为不常使用而被swap到磁盘上了,swap相关的命令如下:
swapon 开启swap swapoff 关闭swap /proc/sys/vm/swapiness 分值越大越积极使用swap,可以修改/etc/sysctl.conf中添加vm.swappiness=xx[1-100]来修改
如果内存是mmap映射到内存中的,那么在读、写对应内存的时候也会产生缺页异常。
在Linux中,内存管理是一个复杂的主题,但是如果程序员能够理解并充分利用它,他们可以极大地提高他们的程序的性能和可靠性。在本文中,我们介绍了Linux内存管理的基本知识、虚拟内存的概念、内存映射文件以及交换空间等。此外,我们还介绍了一些有助于程序员优化内存使用的技巧和工具。现在,不要再让程序的性能拖慢了你的项目,去掌握Linux内存管理吧!
The above is the detailed content of Master Linux memory management and improve your program performance!. For more information, please follow other related articles on the PHP Chinese website!