尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Linux内存Overcommit机制:三种策略、OOM Killer算法与cgroup限制行为的工程化分析
Linux内存Overcommit机制三种策略、OOM Killer算法与cgroup限制行为的工程化分析一、为什么Linux允许超额分配内存物理内存是有限资源但进程的内存请求远大于实际使用量。典型场景进程malloc了1GB但只写了100MB剩余900MB从未触碰。如果内核拒绝所有超额请求大量内存被浪费在已申请但未使用的状态。Overcommit机制允许内核在malloc时只记录分配意向物理页面在首次写入时才真正分配缺页中断触发。代价是当所有进程的意向总量超过物理内存swap时内核必须杀死某些进程来释放内存——这就是OOM Killer。二、vm.overcommit_memory的三种策略内核通过vm.overcommit_memory参数控制Overcommit行为取值0、1、2值策略名行为适用场景0heuristic内核智能判断允许合理超额但不允许明显不可能的请求通用服务器1always总是允许不做任何检查科学计算、大数据内存使用模式可预测2never不允许超额分配总量不超过overcommit_ratio%×物理内存swap关键业务、内存敏感型数据库heuristic模式的判断逻辑heuristic模式下内核计算已提交内存Committed_AS与可用内存的关系。当请求的分配量使Committed_AS超过以下阈值时拒绝阈值 物理内存 swap slab可回收内存内核不会精确计算——它允许一定量的超额因为经验表明大部分malloc不会被全部使用。但极端超额请求如一个进程申请超过可用内存总量会被拒绝。never模式的精确限制never模式使用vm.overcommit_ratio默认50计算允许的总量上限CommitLimit (物理内存 × overcommit_ratio/100) swap对于2GB物理内存、1GB swap、overcommit_ratio50的系统CommitLimit 1GB 1GB 2GB。超过2GB的malloc请求将被拒绝并返回ENOMEM。OOM触发流程flowchart TD A[进程调用malloc/mmap] -- B{overcommit_memory策略} B --|0 heuristic| C[内核智能判断] B --|1 always| D[直接允许分配] B --|2 never| E[检查CommitLimit] C -- F{合理超额?} F --|是| D F --|否| G[返回ENOMEM] E -- H{Committed_AS ≤ CommitLimit?} H --|是| D H --|否| G D -- I[记录分配意向] I -- J[进程首次写入内存页] J -- K[触发缺页中断] K -- L{物理内存swap有可用页?} L --|是| M[分配物理页 映射到进程] L --|否| N[触发OOM Killer] N -- O[计算各进程oom_score] O -- P[选择最高分进程] P -- Q[杀死选中进程] Q -- R[释放内存] R -- M style N fill:#e74c3c,color:#fff style G fill:#e74c3c,color:#fff三、OOM Killer的选择算法oom_score_adj的工程机制OOM Killer的目标是选择最该死的进程。评分逻辑oom_score 进程内存占用占比 × 1000 oom_score_adjoom_score_adj是可调的偏移值范围-1000~1000-1000进程永远不会被OOM Killer选中如sshd、系统关键服务0默认值纯按内存占比排序1000进程优先被选中如非关键的后台任务评分计算细节内核遍历所有进程对每个进程计算进程的RSS驻留内存集占系统总可用内存的百分比进程的swap占系统总swap的百分比两者相加后乘以1000得到基础分加上oom_score_adj得到最终分分数最高的进程被选中杀死/* 内核 oom_badness() 的核心逻辑简化版 */ long oom_badness(struct task_struct *p, long totalpages) { long points; long adj; adj p-signal-oom_score_adj; if (adj OOM_SCORE_ADJ_MIN) { /* -1000: 不可杀死 */ return LONG_MIN; } points get_total_mm_pages(p) * 1000 / totalpages; points adj; return points; }工程实践中的关键操作# 保护关键服务不被OOM杀死 echo -1000 /proc/$(pidof sshd)/oom_score_adj # 让非关键后台任务优先被杀死 echo 500 /proc/$(pidof log_aggregator)/oom_score_adj # 查看当前OOM评分 cat /proc/$(pidof mysqld)/oom_score四、cgroup内存限制的实际行为与Overcommit的交互cgroup v1的memory.limit_in_bytes和cgroup v2的memory.max设置了进程组的内存上限。关键问题cgroup限制与Overcommit如何交互行为规则cgroup限制是物理限制当进程组的内存使用达到limit时内核触发cgroup级别的回收回收文件页、swap出匿名页回收失败后触发cgroup OOM如果回收后仍超限内核在cgroup范围内执行OOM Killercgroup OOM与全局OOM独立cgroup内OOM不会触发全局OOM Killer只在cgroup范围内选择进程Overcommit策略仍然生效cgroup内的malloc请求仍受vm.overcommit_memory策略约束cgroup内存限制的C代码演示#include stdio.h #include stdlib.h #include string.h #include unistd.h #include sys/mman.h /* * 在cgroup内存限制下测试Overcommit行为 * 编译: gcc -o oom_test oom_test.c * 运行前设置cgroup限制: * echo 100M /sys/fs/cgroup/test/memory.limit_in_bytes * echo $$ /sys/fs/cgroup/test/cgroup.procs */ #define PAGE_SIZE 4096 #define ALLOC_MB 200 /* 申请200MB超过100MB的cgroup限制 */ int main(void) { size_t total ALLOC_MB * 1024 * 1024; char *region; size_t touched 0; printf(当前进程PID: %d\n, getpid()); printf(申请内存: %d MB\n, ALLOC_MB); /* malloc利用Overcommit只记录意向不分配物理页 */ region malloc(total); if (!region) { perror(malloc失败); return 1; } printf(malloc成功Overcommit允许\n); /* 逐页写入触发缺页中断真正消耗物理内存 */ for (size_t i 0; i total; i PAGE_SIZE) { region[i] 0x42; touched PAGE_SIZE; if (touched % (10 * 1024 * 1024) 0) { printf(已写入: %zu MB\n, touched / (1024 * 1024)); } } /* 如果执行到这里说明cgroup限制未生效或Overcommitalways */ printf(全部写入完成不应到达此处\n); free(region); return 0; }运行结果预期进程在写入约100MB时被cgroup OOM Killer杀死。若Overcommit1且cgroup使用swap可能推迟OOM触发时间。cgroup v2的OOM行为配置# 设置内存硬限制超出即OOM echo 100M /sys/fs/cgroup/test/memory.max # 设置内存软限制超出后优先回收但不OOM echo 80M /sys/fs/cgroup/test/memory.low # 禁用OOM Killer超出限制后进程被挂起等待内存释放 echo 1 /sys/fs/cgroup/test/memory.oom.groupmemory.oom.group是cgroup v2的新特性设置为1时当cgroup触发OOM杀死cgroup内所有进程而非只杀最高分进程。适用于容器场景——容器内所有进程应作为整体被杀死。五、总结Overcommit三种策略heuristic(0)智能判断、always(1)无条件允许、never(2)严格限制never模式通过CommitLimit公式精确控制分配上限OOM Killer评分算法基础分内存占比×1000加上oom_score_adj偏移-1000使进程不可被杀、1000使进程优先被杀cgroup内存限制是物理级别的硬约束回收失败后在cgroup范围内触发OOMcgroup OOM与全局OOM独立运作cgroup v2新增memory.low软限制和memory.oom.group整体杀死特性更适合容器化场景的内存管理Overcommit策略与cgroup限制叠加生效cgroup限制物理使用量Overcommit策略控制malloc阶段的逻辑分配量两者分别在不同层面约束内存行为
RELATED

相关推荐

从AIGC到AIGS:企业AI落地的新范式

从AIGC到AIGS:企业AI落地的新范式

从AIGC到AIGS:企业AI落地的新范式过去几年,很多企业在AI落地的过程中都有过类似的体验:投入资源搭建了大模型对话系统,上线后却发现它只能回答预设范围内的问题,真正要对接业务系统完成具体操作时,处处都是…

📅 2026/9/19 22:04:50
Arachni 与 OWASP ZAP 对比评测:3大维度实测扫描速度与漏洞检出率

Arachni 与 OWASP ZAP 对比评测:3大维度实测扫描速度与漏洞检出率

Arachni 与 OWASP ZAP 深度对比:从扫描效率到漏洞检测的实战评测在当今快速迭代的Web应用开发环境中,安全扫描工具的选择直接影响着漏洞发现的效率和质量。作为两款备受关注的开源解决方案,Arachni和OWASP ZAP在技术架构、检测能力和适用场景…

📅 2026/11/4 0:37:03
2026年上海改灯:一物一码可查的选择与实用攻略

2026年上海改灯:一物一码可查的选择与实用攻略

一、开头:技术痛点/趋势引入2026年,随着汽车保有量的持续增长以及人们对夜间行车安全重视程度的不断提高,改灯领域面临着新的挑战与机遇。在技术交流群里,经常有人询问改灯到底该如何进行选型。从架构演进、性能、成本、运维复杂度…

📅 2026/10/31 3:34:44
MORE NEWS

更多资讯

📰

uniapp海外游戏分发工程:PG电子集成与Switch卡带区域适配

简介:这是一套面向海外游戏业务开发者的全栈前端解决方案,基于UniApp框架实现跨平台兼容,专为构建海外游戏交易平台、手游下载站及Switch游戏卡带销售系统设计。资源包含完整可二次开发的前端源码(非编译后产物)&#…

📰

Qoder NEXT:智能代码补全工具的技术解析与应用

1. 项目概述Qoder NEXT作为新一代智能编程辅助工具,其核心突破在于通过深度优化代码补全算法,将AI生成代码的开发者采纳率提升了65%。这个数字背后代表着编程效率的实质性飞跃——开发者不再需要花费大量时间在重复性代码编写和机械性调试上,…

📰

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

📰

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

📰

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

📰

Go并发调度器MPG模型与工作窃取算法解析

1. Go并发调度器的设计哲学Go语言最引以为傲的特性就是其原生支持的并发模型。与传统的线程池方案不同,Go的并发调度器采用了一种称为MPG模型的独特设计。这种设计源于Rob Pike等人对现代多核处理器架构的深刻理解——当CPU核心数量越来越多时,基于操作系…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬