Linux系统下mmap()的物理页实际分配机制相关问询
Linux内存分配与mmap机制说明
首先纠正一个常见误解:开启内存过量提交时不会立刻分配物理页
无论过量提交功能是否开启,用户态调用mmap()申请和WindowsVirtualAlloc对应的匿名私有映射时,默认都不会立刻分配物理内存页,都是等到进程首次访问该虚拟地址区间的对应页时,触发缺页异常后内核才会实际分配物理页、建立页表映射,这个缺页处理的延迟和Windows场景量级一致,通常在数百到上千时钟周期区间。
不同过量提交策略下的预留逻辑差异
Linux的过量提交行为由内核参数vm.overcommit_memory控制,三种取值对应完全不同的处理逻辑:
- 值为0(默认启发式过量提交):内核会估算当前系统可分配内存总和(空闲物理页+可回收缓存页+交换分区剩余空间),如果申请的内存大小明显超过该值会直接返回
ENOMEM错误,否则允许申请。该模式下不会提前扣除交换分区空间,完全等到缺页触发时再处理资源分配,如果实际分配时无可用内存也无交换空间,会触发OOM Killer终止优先级较低的进程释放资源。 - 值为1(强制允许过量提交):不对申请大小做任何检查,无论申请多大内存都直接允许,仅在缺页时实际无资源可用时才触发OOM,适合存在大量稀疏内存访问的场景(如科学计算、虚拟机超配)。
- 值为2(关闭过量提交,严格分配模式):这是最接近你描述的预留逻辑的模式,内核会提前设定可分配内存上限:
物理内存总量 * vm.overcommit_ratio(默认50%) + 交换分区总剩余空间,进程申请的内存总大小不可超过该上限。调用mmap()申请匿名映射时,内核会从可分配配额中扣除对应空间,相当于提前向进程承诺该内存后续访问时一定可以分配成功,不会出现访问时分配失败的问题。
关闭过量提交时和Windows机制的异同
相同点:不管是Windows的
VirtualAlloc(MEM_RESERVE | MEM_COMMIT),还是Linux关闭过量提交后的mmap()匿名映射,都不会立刻分配物理页,都是首次访问页时触发动态映射,都存在千级时钟周期左右的缺页延迟。
不同点:Windows是提前从页文件中扣除预留空间,Linux严格过量提交模式下是从「物理内存配额+交换分区总剩余」的合并配额中做记账扣除,不会提前占用交换分区的实际存储,只有当物理内存不足需要页换出时才会实际写入交换分区。
内容的提问来源于stack exchange,提问作者Bonita Montero
相关产品推荐
相关产品推荐

