直接回答:Linux 默认启发式 overcommit(vm.overcommit_memory=0):malloc/mmap 只是记账(建立虚拟地址映射),物理页在首次访问触发缺页中断时才分配。这允许系统“超发”内存——fork 时父子进程共享页表靠 COW 才可行、稀疏申请的内存(如 JVM 的 -Xmx 预留)不立即占物理资源。代价:物理内存耗尽时已无法通过 malloc 返回值报错,内核只能请出 OOM killer 挑进程杀掉。
展开解析:三种策略:0 启发式(明显的超额申请拒绝,日常超额放行);1 永远放行(CAP_SYS_ADMIN 之外也放行,适合明确要 COW 友好的科学计算,危险);2 严格记账(承诺总量不超 swap + RAM×overcommit_ratio,数据库服务器常用——PostgreSQL 官方建议配 2 防 OOM 杀库进程)。OOM killer 的打分(oom_score)按内存占用加权和 oom_score_adj 调整,容器里配合 cgroup 的 memory.max 有局部 OOM。实践要点:监控别只看 RSS,看 cgroup 的 memory.events(oom 计数)与 PSI 内存压力;关键服务设 oom_score_adj 保护、非关键的调大让它先死;“内存泄漏”误判——page cache 与 slab 回收不及时会让 free 很少但 available 正常,看 available 不看 free。交换分区与 zram/zswap 是 overcommit 压力下的缓冲层,但 swap 换页抖动(thrashing)比 OOM 更折磨——现代服务端倾向关 swap 接受早死早超生。
追问方向:容器里的 OOM 与宿主机 OOM 如何交互?memory.oom.group 语义是什么?
(约 480 字)