我通读了 man proc 的文档。当涉及到 overcommit_memory 时,overcommit_memory=0 中的启发式并不能很好地理解。启发式的实际含义是什么?
“不检查使用 MAP_NORESERVE 调用 mmap(2)”是否意味着内核仅分配虚拟内存,甚至不知道交换空间的存在?
该文件包含内核虚拟内存计费模式。值为: 0:启发式过量使用(这是默认值) 1:总是过度使用,从不检查 2:经常检查,切勿过度投入 模式0下,使用MAP_NORESERVE的mmap(2)调用不会被检查,默认检查很弱,导致风险 使进程“OOM-killed”。
除了前面的问题之外,无论剩余物理内存是否足够,虚拟地址空间耗尽是否会导致OOM。
谢谢。
答案1
overcommit_memory
内存管理子系统中的三个位置会考虑该设置。
主要的一个是
__vm_enough_memory
inmm/util.c
,它决定是否有足够的内存可供继续进行内存分配(请注意,这是一个不一定被调用的实用函数)。如果overcommit_memory
为 1,则该函数始终成功。如果是 2,则检查实际可用内存。如果它是0,它使用你提到的著名的启发式;其进展如下:- 计算空闲页面的数量
- 添加文件支持页面的数量(这些可以恢复)
- 删除用于共享内存的页面
- 添加交换页
- 添加可回收页面
- 保留页面的帐户
- 为根保留一些内存(如果分配不是由
cap_sys_admin
进程完成的)
所得总数用作内存分配的阈值。
mmap
还检查设置:MAP_NORESERVE
是否允许过量使用(模式 0 和 1),并导致分配没有后备交换 (VM_NORESERVE
)。在这种特殊情况下,模式 0 实际上等同于模式 1;这就是“不检查mmap(2)
with的调用MAP_NORESERVE
”所指的:这意味着MAP_NORESERVE
mmap
调用总是会成功,而过度分配将导致 OOM-killer 在事后介入,或者在尝试写入时出现段冲突。shmem
具有与 类似的行为mmap
。
地址空间用完应该会导致分配失败,而不是 OOM-kills,因为分配实际上无法继续进行。