linux内存工作原理
- 物理内存-虚拟内存-MMU之间的关系
- 进程内存用户空间-内核空间
- 内存分配与回收机制
- 内存查看相关指标
虚拟内存空间分布首先,我们需要进一步了解虚拟内存空间的分布情况。最上方的内核空间不用多讲,下方的用户空间内存,其实又被分成了多个不同的段。以 32 位系统为例,我画了一张图来表示它们的关系。通过这张图你可以看到,用户空间内存,从低到高分别是五种不同的内存段。只读段,包括代码和常量等。数据段,包括全局变量等。堆,包括动态分配的内存,从低地址开始向上增长。文件映射段,包括动态库、共享内存等,从高地址开始向下增长。栈,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。
内存分配与回收
malloc() 是 C 标准库提供的内存分配函数,对应到系统调用上,有两种实现方式,即 brk() 和 mmap()。
对小块内存(小于 128K),C 标准库使用 brk() 来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统,而是被缓存起来,这样就可以重复使用。
而大块内存(大于 128K),则直接使用内存映射 mmap() 来分配,也就是在文件映射段找一块空闲内存分配出去。这两种方式,自然各有优缺点。
系统也不会任由某个进程用完所有内存。在发现内存紧张时,系统就会通过一系列机制来回收内存,比如下面这三种方式:
回收缓存,比如使用 LRU(Least Recently Used)算法,回收最近使用最少的内存页面;
回收不常访问的内存,把不常用的内存通过交换分区直接写到磁盘中;
杀死进程,内存紧张时系统还会通过 OOM(Out of Memory),直接杀掉占用大量内存的进程