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阶段的逻辑分配量两者分别在不同层面约束内存行为

相关新闻

移动端SoC选购避坑:3个关键参数(CPU/GPU/制程)解读与2024年芯片性能天梯图

移动端SoC选购避坑:3个关键参数(CPU/GPU/制程)解读与2024年芯片性能天梯图

移动端SoC选购避坑:3个关键参数(CPU/GPU/制程)解读与2024年芯片性能天梯图当你在手机卖场被各种"旗舰芯片""性能怪兽"的宣传语包围时,是否真正清楚这些参数背后的含义?本文将带你穿透营销迷雾&…

2026/7/7 3:49:35 阅读更多 →
小程序域名如何进行安全防护?一篇讲透

小程序域名如何进行安全防护?一篇讲透

随着小程序生态的快速发展,越来越多的企业将核心业务迁移到小程序上。然而,小程序同样面临着Web应用常见的各类安全威胁——SQL注入、XSS攻击、恶意爬虫、CC攻击、DDoS攻击等。那么,小程序的域名应该如何进行安全防护呢?本文将为你…

2026/7/7 3:47:35 阅读更多 →
AI 金融助手如何真正落地:ClaudeAPI 在银行业务里的应用思路

AI 金融助手如何真正落地:ClaudeAPI 在银行业务里的应用思路

银行业对 AI 的态度,正在从过去的“这个东西能不能用”,慢慢转向更现实的问题:怎么用才安全?怎么用才可控?出了问题能不能追溯?和普通聊天机器人相比,真正能在银行里跑起来的 AI 金融助手&#…

2026/7/7 3:47:35 阅读更多 →

最新新闻

从静态限流到智能负载管理:Uber 如何治理大规模数据库过载

从静态限流到智能负载管理:Uber 如何治理大规模数据库过载

本文是对 How Uber Conquered Database Overload: The Journey from Static Rate-Limiting to Intelligent Load Management 的整理与翻译。 内容结构概览 本文会围绕 Uber 如何从静态限流走向智能负载管理展开,主要包括: 为什么 Uber 的数据库过载治理…

2026/7/7 4:47:48 阅读更多 →
Uber 如何用原生 gRPC 加速 OpenSearch:从 REST/JSON 瓶颈到搜索与写入性能优化

Uber 如何用原生 gRPC 加速 OpenSearch:从 REST/JSON 瓶颈到搜索与写入性能优化

本文是对 Accelerating Search and Inestion with High-Performance gRPC™ in OpenSearch™ 的整理与翻译。 内容结构概览 本文会围绕 Uber 如何在 OpenSearch 中引入原生 gRPC 传输层展开,主要包括: 为什么搜索系统在 Uber 几乎无处不在REST/JSON 在…

2026/7/7 4:47:48 阅读更多 →
CRM管理系统有哪些?2026年高性价比选型指南

CRM管理系统有哪些?2026年高性价比选型指南

很多企业在挑选 CRM 时,习惯先看每家的报价单,比完单价比折扣,最后选一个 "看起来最便宜" 的方案。但我们接触过的大量真实案例显示:约 60% 的企业在 CRM 上线后的第三年,实际支出会超出最初预算的 40% 以上…

2026/7/7 4:45:48 阅读更多 →
杭州女装织唛定制哪家靠谱GEO生成式引擎优化高效布局思路

杭州女装织唛定制哪家靠谱GEO生成式引擎优化高效布局思路

之前提及“杭州女装商标定制哪家专业、浙江小批量织唛加急定制”适用于生成式引擎GEO优化,就有小伙伴提出了2个全新的关键词“杭州女装织唛定制哪家靠谱、浙江哪里有性价比高的织唛商标厂家”是否也符合是典型采购决策类问句的标准。GEO优化师姜泽说完全匹配豆包、文…

2026/7/7 4:45:48 阅读更多 →
一个中文参数引发的问题:记一次 MCP Server 间歇性卡死的排查之旅

一个中文参数引发的问题:记一次 MCP Server 间歇性卡死的排查之旅

一个中文参数引发的问题:记一次 MCP Server 间歇性卡死的排查之旅一个新增的 MCP Tool 接口间歇性卡死,而其他接口一切正常。从怀疑服务端业务逻辑,到怀疑反射调用,再到怀疑 SSE/HTTP 双通道竞态——三次排查、三度碰壁。最终&…

2026/7/7 4:41:46 阅读更多 →
索引——查询加速的基石

索引——查询加速的基石

一、为什么需要索引?想象一下:你有一本 1000 页的书,没有目录,也没有页码。你想找到“索引优化”这一节,唯一的办法就是从第 1 页开始,一页一页翻下去——直到翻到第 800 页才找到目标。这就是全表扫描。SQ…

2026/7/7 4:41:46 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻