Linux伙伴系统:内存管理核心算法解析
1. 伙伴系统基础概念解析伙伴系统Buddy System是Linux内核中用于管理物理内存页的核心算法之一最早由Donald Knuth提出并应用于操作系统领域。它的核心思想是将内存划分为不同大小的块每个块都是2的幂次方页通常一页为4KB通过递归合并和分割的方式高效管理内存分配与释放。在Linux内核中伙伴系统主要管理order 0到order 10的连续物理页框对应从1页4KB到1024页4MB的内存块。这种设计特别适合处理外部碎片问题——当系统长时间运行后内存中会出现大量不连续的小碎片导致无法分配大块连续内存。伙伴系统通过以下机制解决这个问题分级管理将内存按2^n大小分到11个MAX_ORDER通常为11不同阶order的链表中伙伴合并释放内存时会检查相邻的伙伴块是否空闲是则合并成更大的块分割机制当没有合适大小的块时会将更大的块对半分割直到得到所需大小关键理解所谓伙伴是指两个大小相同、物理地址连续且低位地址必须能被2^(order1)整除的内存块。例如两个4页的块如果第一个块的起始地址是0x1000那么它的伙伴必须是0x2000。2. Linux内核中的伙伴系统实现细节2.1 核心数据结构剖析Linux内核通过以下数据结构实现伙伴系统struct zone { ... struct free_area free_area[MAX_ORDER]; ... }; struct free_area { struct list_head free_list[MIGRATE_TYPES]; unsigned long nr_free; }; struct page { ... union { struct { /* 伙伴系统使用 */ unsigned long private; struct page *first_page; }; ... }; ... };每个内存区域zone维护一个free_area数组数组下标对应order值。free_area中的free_list是不同迁移类型MIGRATE_TYPES的空闲链表用于实现反碎片技术。nr_free记录该order下的空闲块总数。2.2 内存分配流程解析当内核需要分配连续物理页时主要经历以下步骤确定分配阶根据请求大小计算最小满足的order值order fls(size/PAGE_SIZE) - 1; // 找最高位1的位置查找空闲块从计算的order开始向上遍历free_area数组找到第一个非空的free_list链表如果找到的order大于请求order执行块分割块分割操作while (current_order order) { area-nr_free--; list_del(page-lru); current_order--; new_page page (1 current_order); set_page_order(new_page, current_order); list_add(new_page-lru, zone-free_area[current_order].free_list); }标记页面状态设置page结构的private字段为order值清除PG_buddy标志增加zone的vm_stat[NR_ALLOC_BATCH]计数2.3 内存释放流程解析释放内存时伙伴系统执行相反操作合并准备struct page *buddy; buddy __find_buddy_page(page, page_order, page_idx);递归合并检查伙伴块是否空闲PG_buddy标志且order相同如果可合并从链表中删除伙伴块合并后的块order加1重复上述过程直到无法合并或达到MAX_ORDER-1最终插入list_add(page-lru, zone-free_area[order].free_list); set_page_order(page, order); __mod_zone_page_state(zone, NR_FREE_PAGES, 1 order);3. 伙伴系统的高级特性与优化3.1 反碎片技术实现Linux 2.6.24引入迁移类型MIGRATE_TYPES来减少内存碎片enum migratetype { MIGRATE_UNMOVABLE, // 不可移动页内核核心数据 MIGRATE_RECLAIMABLE, // 可回收页文件缓存等 MIGRATE_MOVABLE, // 可移动页用户空间内存 MIGRATE_PCPTYPES, // per-cpu pageset使用 MIGRATE_HIGHATOMIC, // 紧急原子分配 MIGRATE_CMA, // 连续内存分配器 MIGRATE_ISOLATE, // 不能分配从此区域 MIGRATE_TYPES };每个free_area的free_list数组按迁移类型分开管理分配时优先从相同类型的链表中获取。当特定类型内存不足时内核会尝试fallback机制按照MOVABLE→RECLAIMABLE→UNMOVABLE顺序回退内存压缩通过移动页面整理出连续空间直接回收回收可回收页面的缓存3.2 每CPU页框缓存为提升单页order0分配性能内核实现了每CPU缓存struct per_cpu_pages { int count; // 列表中页数 int high; // 填充水位线 int batch; // 添加/移除块大小 struct list_head list; // 页链表 }; struct per_cpu_pageset { struct per_cpu_pages pcp; };当分配单页时优先从当前CPU的pcp-list获取如果空则从伙伴系统批量获取pcp-batch个页释放单页时先放入pcp-list当count pcp-high时返还部分给伙伴系统4. 伙伴系统性能调优与实践4.1 关键内核参数调整通过/proc/sys/vm调整伙伴系统行为水位线控制/proc/sys/vm/min_free_kbytes // 最小保留内存 /proc/sys/vm/lowmem_reserve_ratio // 各zone保留比例分配策略调整/proc/sys/vm/zone_reclaim_mode // 内存回收策略 /proc/sys/vm/extfrag_threshold // 碎片化告警阈值透明大页配置/sys/kernel/mm/transparent_hugepage/enabled /sys/kernel/mm/transparent_hugepage/defrag4.2 诊断工具与方法查看伙伴系统状态cat /proc/buddyinfo # 输出示例 # Node 0, zone Normal 11 10 8 7 5 3 2 1 1 1 1检查内存碎片cat /proc/pagetypeinfo使用vmstat观察vmstat -m | grep -E ^DMA|^Normal内核追踪点perf probe --add alloc_pages perf probe --add free_pages4.3 实际应用中的经验技巧大块内存分配优化对于需要大于4MB的连续内存考虑alloc_pages(GFP_HIGHUSER | __GFP_COMP | __GFP_NORETRY, order);或使用CMA连续内存分配器区域避免内存碎片技巧长时间运行的服务应预先分配关键内存不同生命周期的对象使用不同迁移类型定期检查/proc/buddyinfo的碎片情况调试内存泄漏echo 1 /proc/sys/vm/oom_dump_tasks dmesg | grep -i out of memory5. 伙伴系统的局限与替代方案5.1 现有架构的不足大块内存分配问题默认MAX_ORDER11限制最大连续分配4MB解决大块需求需修改内核参数或特殊配置内存碎片挑战长期运行后仍可能产生不可移动碎片特别是UNMOVABLE类型内存的积累NUMA架构扩展性跨节点内存分配效率较低需要明确的NUMA感知分配策略5.2 替代方案比较SLUB分配器更适合小对象分配减少内部碎片但无法解决外部碎片CMA连续内存分配器预留物理连续内存区域需要设备树或内核参数配置用户空间方案posix_memalign() // 对齐分配 mmap(MAP_HUGETLB) // 大页映射5.3 未来演进方向基于CXL的内存池化打破物理内存的本地性限制实现更灵活的内存共享机制机器学习预测分配根据历史模式预分配内存减少实时分配的开销异构内存管理统一管理DRAM、PMem等不同介质自动将热页迁移到更快介质

相关新闻

AI多平台协作框架:Claude、ChatGPT与Notion的协同实践

AI多平台协作框架:Claude、ChatGPT与Notion的协同实践

1. 项目背景与核心价值 这个项目本质上是一次跨越多个AI平台的协作实验,通过"君子协议"这种非正式但高度信任的合作方式,探索不同AI系统间的协同可能性。我在过去三个月里,深度使用了Claude、ChatGPT和Notion三个平台,发…

2026/10/20 22:20:54 阅读更多 →
TMS570 VIM与ESM模块解析:构建高可靠嵌入式系统的中断与错误管理基石

TMS570 VIM与ESM模块解析:构建高可靠嵌入式系统的中断与错误管理基石

1. 项目概述与核心价值 在嵌入式系统开发,尤其是汽车电子、工业控制这类对实时性和可靠性要求极高的领域,中断和错误处理机制的设计水平,直接决定了整个系统的“天花板”。很多工程师在项目初期,往往只关注功能实现,对…

2026/10/20 6:20:56 阅读更多 →
解决highlight.php常见问题:开发者必备的故障排除手册

解决highlight.php常见问题:开发者必备的故障排除手册

解决highlight.php常见问题:开发者必备的故障排除手册 【免费下载链接】highlight.php A port of highlight.js by Ivan Sagalaev to PHP 项目地址: https://gitcode.com/gh_mirrors/hi/highlight.php highlight.php是一款将highlight.js移植到PHP的代码高亮…

2026/10/20 11:59:13 阅读更多 →

最新新闻

WebRTC拥塞控制核心:AimdRateControl原理与实战调优

WebRTC拥塞控制核心:AimdRateControl原理与实战调优

1. 项目概述:为什么一个“码率控制器”值得你花20分钟认真读完在WebRTC的实际工程落地中,90%的卡顿、花屏、延迟抖动问题,最终都指向同一个被低估的模块——AimdRateControl。它不是WebRTC协议栈里最炫酷的部分,没有SDP协商那么直…

2026/10/20 22:20:53 阅读更多 →
从零搭建群聊自动化Bot:环境配置、创建与部署实战

从零搭建群聊自动化Bot:环境配置、创建与部署实战

1. 从零搭建一个能干活儿的 Bot:整体思路与方案选型1.1 这个 Bot 到底能干什么,适合谁来折腾先把话说在前头:这篇东西讲的不是那种"跑个 demo 就完事"的玩具,而是一套能真正拉进群里、替你分担重复劳动的自动化助手。核…

2026/10/20 22:20:53 阅读更多 →
Claude Code 安装排坑指南:从环境检查到命令行实战

Claude Code 安装排坑指南:从环境检查到命令行实战

不知道你有没有见过这种场面:一个开发者看了一篇安装教程,前十分钟每一步都照做了,结果在最后启动命令时直接卡住,界面白屏、报错刷屏,只能把窗口关掉重新再来。身边最近讨论新一代命令行 AI 编程助手的声音挺大&#…

2026/10/20 22:20:53 阅读更多 →
Kubernetes入门:Ubuntu环境下k8s集群搭建实操与避坑指南

Kubernetes入门:Ubuntu环境下k8s集群搭建实操与避坑指南

有朋友让我聊聊 k8s 到底是个啥,顺便给一套能在 Ubuntu 上把环境跑起来的实操流程。这话题我前前后后折腾了不少次,从最早只会跑 docker 容器,到后来维护几个节点的集群,中间踩的坑不算少。这篇就结合我自己的实操经验&#xff0c…

2026/10/20 22:20:53 阅读更多 →
OpenClaw消息总线架构拆解:从SQLite队列到Agent运行时设计

OpenClaw消息总线架构拆解:从SQLite队列到Agent运行时设计

1. 项目概述与核心命题拆解1.1 这个项目到底在做什么OpenClaw 是一个开源的个人 AI 助理框架,核心定位是让用户通过日常聊天工具(如即时通讯软件)直接操控一台远程计算机,完成文件管理、代码执行、网页浏览、定时任务等操作。它不…

2026/10/20 22:20:53 阅读更多 →
Obsidian标签体系完整拆解:四种方案对比与落地模板

Obsidian标签体系完整拆解:四种方案对比与落地模板

开头笔记软件换了又换,最后能让我一直留下来的,反倒是 Obsidian 里那套看起来不起眼的标签系统。我见过不少人把 Obsidian 当成文件夹管理器,一个笔记塞进一个目录,回头找资料就翻了天;也见过更夸张的,半年…

2026/10/20 22:19:42 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →