内存管理-内存回收
内存满了会有什么处理?什么情况下会触发内存回收?OOM是什么?
1. 有几种内存回收的方式?
- 后台内存回收
- 直接内存回收
- 触发OOM机制
1.1 内存分配过程
- 当使用malloc分配内存的时候,分配的是虚拟内存;
- 当访问该内存的时候,通过映射表查找虚拟内存对应的物理内存。此时发现并没有对应的映射表,于是触发缺页中断;
- 缺页中断处理程序在堆区中查找空闲内存,如果存在,则直接返回物理内存,如果不存在,先进行内存回收,再返回内存;
- 首先通过后台内存回收的方式回收空闲内存,这个过程是异步的;
- 当后台内存回收的速度跟不上内存申请的速度时,触发直接内存回收,这个过程是同步的,会阻塞线程;
- 当直接内存回收也无法满足要求时,会触发OOM机制。
2. 哪些内存可以直接被回收?
- 文件页
- 匿名页
2.1 文件页
什么是文件页?
- 文件页是指与磁盘文件存在映射关系的内存页,页面的内存可以直接映射到某个具体的文件位置上。
文件页有哪些?
- 内核缓存的磁盘数据(Buffer):用于缓存磁盘块设备的数据;
- 内核缓存的文件数据(Cache):用于缓存文件系统的数据,例如通过read系统调用读取的文件内容;
- 进程代码块:可执行文件的代码部分在内存中的映射;
- 文件映射页:通过mmap系统调用将文件映射到进程的地址空间,例如共享库或用户通过mmap映射的文件;
- 脏页:被应用程序修改过但尚未写入磁盘的文件页,需要先写回磁盘后才能释放内存;
文件页的回收方式:
- 对于干净页:可以直接释放内存,后续需要时再从磁盘重新读取;
- 对于脏页:必须先写回磁盘,然后再释放内存;
2.2 匿名页
匿名页的特点:
- 无文件背景:匿名页不与任何磁盘文件关联,这是它和文件页最主要的区别。匿名页存储的是进程运行时动态生成的数据,例如堆,栈,共享文件等;
- 临时性:数据由进程运行时产生,生命周期与进程绑定,进程退出后匿名页会被释放;
- 依赖Swap机制:由于没有磁盘文件作为后被存储,匿名页的回收需要swap分区或者swap文件实现;
匿名页常见的类型:
- 动态内存分配:通过malloc,calloc等分配的堆内存;
- 进程栈空间:函数调用时的局部变量和函数栈帧;
- 共享内存:进程间通讯的共享内存区域;
- 写时复制:使用fork()产生的子进程内存页;
匿名页的生命流程:
- 分配:
- 通过系统调用(mmap/brk)或库函数(malloc)分配虚拟内存;
- 首次访问时触发缺页中断,内核分配物理内存并建立映射;
- 使用:
- 进程通过虚拟内存直接访问匿名页内容;
- 回收(swap机制)
- 换出:内存不足时,内核将不活跃的匿名页写入swap分区/文件,释放物理内存;
- 换入:进程再次访问时,触发缺页中断,从swap中重新加载数据到内存;
- 销毁:
- 进程退出时,内核释放所有关联的匿名页和swap空间。
3. 内存回收带来的性能影响
文件页的回收:
- 对于干净页是直接回收的,不会影响性能;
- 对于脏页,需要先写回磁盘再释放内存,这个操作会影响系统性能;
匿名页的回收:
- swap机制会将不常访问的匿名页换出到磁盘,下次访问时再换入到内存,这个操作会影响系统性能;
3.1 怎么避免内存回收带来的性能影响?
- 调整文件页和匿名页的回收倾向,优先文件页的回收;
- 可以通过调整
swappiness选项来调整回收倾向; swappiness数值越大,越倾向于使用swap,所以可以将其设置最小即0;
- 可以通过调整
- 尽早触发kswapd内核线程异步回收内存;
- 通过增大
min_free_kbytes提前触发kswapd异步回收;
- 通过增大
3.2 什么时候需要调整内存回收策略?
通过 sar -B 1观察 pgscand/s和 pgscank/s的比值,若 pgscand/s持续高位,则说明需要调整内存回收策略。
pgscank/s:由kswapd(后台内存回收线程)每秒扫描的页面数量;pgscand/s:应用程序在内存申请过程中直接触发同步扫描的页面数量,属于直接内存回收;pgsteal/s:每秒从扫描的页面(pgscank+pgscand)中成功回收的页面数量,反映了回收效率;
3.3 系统卡顿与内存直接回收有什么关系?
当系统内存紧张时,如果kswapd后台回收不及时(pgscank/s较低),应用程序会频繁触发直接内存回收,直接内存回收是同步操作,会导致进程阻塞,从而引发系统卡顿。
3.4 什么时候触发kswapd内核线程回收内存?
内核定义了三个内存阈值用来衡量当前内存情况:
- pages_min:页最小阈值
- pages_low:页低阈值
- pages_high:页高阈值
当剩余内存低于pages_low但高于pages_min时,触发kswapd内核线程回收内存,直到剩余内存大于pages_high为止。
当剩余内存低于pages_min时,会触发直接内存回收,此时应用程序会阻塞。
3.5 min_free_kbytes设置过大会有什么影响?
1 | |
pages_min以下的内存属于系统的自留内存,不会给普通进程申请使用。所以 min_free_kbytes设置过大会导致应用进程可用的内存减少,从而可能会频繁的导致OOM的发生。
4. NUMA架构下的内存回收策略
4.1 什么是NUMA架构
NUMA是非一致内存访问架构,是为了解决SMP扩展性问题提出的架构,将多个CPU分组为节点,每个节点拥有本地内存和I/O资源,节点间通过高速互联(QPI)通信。
- 非一致内存访问:CPU访问本地内存速度远快于访问其他节点的内存;
- 模块化设计:每个节点类似于一个小型SMP系统,支持更高的扩展性;
4.2 什么是SMP架构
SMP是一种对称多处理器架构,所有CPU共享同一物理内存,I/O设备和总线,并执行单一操作系统。
- 对称性:所有CPU地位平等,无主从之分,均可访问相同的内存和I/O资源;
- 统一内存访问:所有CPU访问内存的延迟一致;
- 扩展性有限制:随着CPU数量增加,共享总线和内存竞争会成为瓶颈;
4.3 NUMA内存回收策略
有4种模式,通过 /proc/sys/vm/zone_reclaim_mode控制:
- 0(默认值):当本地内存满了之后,先在其他Node寻找空闲内存,如果没找到再回收本地内存;
- 1:当本地内存满了之后,只回收本地内存,即便其他Node有空闲也不去找;
- 2:只回收本地内存,在回收本地内存的时候,可以将文件页的脏页写回磁盘来回收内存;
- 4:只回收本地内存,在回收本地内存的时候,可以使用swap方式回收内存。
5. 由内存回收导致的性能影响,解决方式有哪些?
- 设置
/proc/sys/vm/swappiness,调整文件页和匿名页的回收倾向,优先回收文件页; - 设置
/proc/sys/vm/min_free_kbytes,调整kswapd内核线程异步回收内存的机制,尽早触发kswapd内核线程异步回收内存; - 设置
/proc/sys/vm/zone_reclaim_mode,调整NUMA架构下内存回收策略,选取默认值0,使得在回收本地内存之前,先去其他Node寻找空闲内存;
内存管理-内存回收
http://example.com/2025/05/13/OperatingSystem/内存管理-内存回收/