虚拟内存申请先经过三种 overcommit 准入政策之一;后续物理需求仍受 cgroup、NUMA 及其他资源约束。

Linux overcommit 为虚拟内存承诺设定政策

Linux 的 overcommit 政策控制某些虚拟内存承诺是否可以获准,和分配常驻物理页、选择 OOM 牺牲进程、执行容器内存限制并不是同一件事。一次成功申请可能早于实际物理需求,但这不表示所有分配都没有成本,也不保证后续访问在任何资源约束下都能成功。分析时应把承诺、驻留和故障处理分别记录,而不是都称为“剩余内存”。 虚拟承诺不同于实际驻留 malloc 等分配器可能通过 brk 或 mmap 取得内存,也可能直接复用已有内存区,不发起新的系统调用。匿名页通常按需填入,但地址空间元数据、页表以及实际缺页过程仍然消耗资源。具体成本取决于应用申请什么、访问什么,不能把延迟分配简化成近乎免费地运行整个进程。 Committed_AS 是记账数量,不是所有进程常驻集之和,也不是当前内存压力读数。映射类型会影响成本:私有可写映射可能在页面尚未全部驻留时就形成承诺,普通共享或只读文件映射则采用不同规则。因此,虚拟大小很大的进程未必就是物理内存短缺的责任方,应同时查看实际使用和对应记账范围。 三种准入政策 模式零是默认启发式政策,拒绝明显超额的申请,同时允许超过简单常驻内存预算的分配。它的判断不等于为每个获准字节准备专属 RAM。模式一跳过 overcommit 准入检查,有助于某些稀疏工作负载,但地址空间上限、映射数量以及其他分配失败仍然存在,不能描述成任何荒谬请求都会被无条件接受。 模式二执行更严格的承诺记账。名义 CommitLimit 来自交换空间加上配置的内存额度:比例计算会扣除预留给 hugetlb 的内存,非零 overcommit_kbytes 则用绝对额度代替比例。内核保留量与调用上下文还会影响实际准入。因此,CommitLimit 与 Committed_AS 的差值是有用背景,不是保证任意调用者都能一次申请成功的最大值,也不是当前可用物理内存。 需要记账的分配如果无法纳入预算,可能立即返回 ENOMEM,使部分容量问题更早暴露,包括 fork 和后续改变映射权限所需的承诺。fork 记账与具体映射及写时复制义务有关,并不是简单把父进程常驻集乘二。有些应用有意保留稀疏地址空间,因此政策变化可能影响启动,即使它们预计不会触碰所有页面。 严格记账不是 OOM 免疫 模式二降低一类超额承诺风险,却不会覆盖 cgroup 内存限制、NUMA 约束、其他内核分配以及所有后续需求。任务仍可能遇到内存分配失败或 OOM 事件。不能承诺选了模式二,某个业务工作进程就绝不会被杀,更不能把这个模式当成服务可靠性的单一开关。 ...

十二月 18, 2027 · 2 分钟 · XB Field Notes
文件经加载器漏斗进入内核;另一条后续写入者箭头可以改变运行值。

sysctl 在运行中调整内核

在 Linux 上,sysctl 通过 /proc/sys 暴露一部分内核参数。它可以观察当前运行状态;有权限的写入则能在不重启的情况下改变状态。配置文件是另一层东西:它要求某个加载器在特定时刻执行赋值。混淆这两层,就会遇到常见故障:磁盘上的配置看起来正确,内核实际使用的却是另一个值。 本文限定 Linux、procps-ng 和 systemd。BSD、macOS 也提供名为 sysctl 的命令,但接口和持久化方式不同。在 macOS 上数出多少个键,不能作为 Linux procfs 接口的验证证据。 先确认正在读取哪个接口 对普通名称来说,kernel.ostype 对应 /proc/sys/kernel/ostype;procps 也接受斜杠分隔符。若名称本身含有字面意义的点号,应遵循工具的分隔规则,不能盲目把所有点替换成斜杠。可用键取决于内核配置、已加载模块和执行环境。不同机器的键集合不保证相同,同一台机器运行期间也可能变化。 procps 的普通输出是 key = value,-n 则只打印值。一次读取成功,说明调用者在当前环境看到了这个值,并不证明持久策略已经生效。有些值还会在观察期间变化。排查时只读取所需键,不能把所有读取都当成无副作用操作:手册明确说明,读取 vm.stat_refresh 会刷新每个 CPU 的统计,因此普通枚举会跳过它。 持久化由具体加载器完成 运行时赋值不会替你生成持久配置文件;反过来,保存配置片段也不会立即改变内核。讨论优先级之前,先确定系统在启动或重载时由哪个组件应用设置。 procps 的 --system 会先根据目录优先级选出文件:高优先级目录中的同名文件遮蔽低优先级副本。选中的片段随后按文件名的字典序应用,不按目录逐层决定最终值;最后再读取 /etc/sysctl.conf。systemd 的 sysctl.d 加载器也结合目录优先级和文件名排序,但不直接读取 /etc/sysctl.conf。发行版仍可能通过配置目录中的链接把这个文件纳入加载范围,因此要检查实际安装,不能只凭路径名称下结论。 ...

十一月 22, 2026 · 1 分钟 · XB Field Notes