Linux内核内存管理月度总结:伙伴系统到slab的核心机制回顾
Linux内核内存管理月度总结伙伴系统到slab的核心机制回顾一、为什么重读内核内存管理7月份我花了三周时间重新梳理Linux内核内存管理模块。起因很有趣团队在做性能优化时遇到了一个诡异的内存碎片问题。排查到最后发现根因是伙伴系统buddy system的order分配行为。那一刻我意识到很多玄学问题的答案都写在教科书里。所以我在7月系统地回顾了从伙伴系统到slab分配器的完整链路。这篇文章是我一个月的学习笔记和验证实验的整理。核心目标不是罗列知识而是建立物理内存→内核分配器→用户态的完整心智模型。二、伙伴系统页面级的分配艺术伙伴系统是内核最底层的物理页分配器。它的核心思想是把物理内存按2的幂次order分组管理。每一组叫做一个free_area从order 04KB到order 104MB。核心数据结构// include/linux/mmzone.h struct free_area { struct list_head free_list[MIGRATE_TYPES]; unsigned long nr_free; }; struct zone { struct free_area free_area[MAX_ORDER]; // ... spinlock_t lock; /* 保护并发访问 */ };伙伴系统的分配逻辑可以简化为计算请求大小对应的order。在对应free_area[order]中查找空闲块。如果没有向order1申请然后分裂。分配后将另一半放入低阶free_area。释放时执行反向操作合并// mm/page_alloc.c (简化) static inline void __free_one_page(struct page *page, unsigned long pfn, struct zone *zone, unsigned int order) { // 检查伙伴是否也空闲 while (order MAX_ORDER - 1) { buddy_pfn __find_buddy_pfn(pfn, order); buddy page (buddy_pfn - pfn); if (!page_is_buddy(buddy, order)) break; // 从当前free_list删除伙伴 del_page_from_free_list(buddy, zone, order); // 合并为order1的块 combined_pfn pfn buddy_pfn; page page (combined_pfn - pfn); pfn combined_pfn; order; } add_to_free_list(page, zone, order); }碎片化类型与对策伙伴系统面临三种碎片碎片类型说明内核对策外部碎片空闲页不连续内存规整compaction内部碎片分配大于需求slab对象级细分迁移碎片不可移动页阻断migrate_type分级迁移类型MIGRATE_TYPES是反碎片的核心机制enum migratetype { MIGRATE_UNMOVABLE, // 内核核心数据结构 MIGRATE_MOVABLE, // 用户态页面可换出 MIGRATE_RECLAIMABLE, // slab等可回收内存 MIGRATE_PCPTYPES, // per-CPU页框 MIGRATE_HIGHATOMIC, // 高阶原子分配 MIGRATE_CMA, // 连续内存分配器 MIGRATE_ISOLATE, // 隔离中的页面 };这个设计保证了即使总空闲内存充足也不会因为可移动页散布而阻塞不可移动内存的分配。三、Slab分配器小而美的对象缓存伙伴系统的最小分配单位是4KB一页。但内核中大量的分配请求远小于一页。比如inode结构体约600字节dentry约200字节。如果每次都用伙伴系统分配一页内部碎片会达到80%以上。Slab分配器就是为了解决这个问题而生的。它的核心思想是对象缓存object caching// 创建专用缓存 struct kmem_cache *my_cache kmem_cache_create( my_struct, sizeof(struct my_struct), // 对象大小 0, // 对齐 SLAB_HWCACHE_ALIGN, // 硬件缓存行对齐 NULL // 构造函数 ); // 分配和释放 struct my_struct *obj kmem_cache_alloc(my_cache, GFP_KERNEL); kmem_cache_free(my_cache, obj);Slab分配器内部有三个层次第一层kmem_cache — 缓存描述符每个kmem_cache对应一种固定大小的对象类型。内核启动时会创建两类缓存专用缓存为特定类型创建如inode_cache、dentry_cache。通用缓存kmalloc使用的预定义大小缓存8, 16, 32, ..., 8192字节。第二层slab — 页面的管理者每个slab管理一个或多个连续物理页。slab有三种状态full所有对象都在使用中。partial部分对象在使用中。empty所有对象都是空闲的。struct slab { struct list_head slab_list; // 链接到缓存的partial/full/empty链表 unsigned long freelist[N]; // 空闲对象位图 void *s_mem; // 第一个对象的地址 unsigned int inuse; // 使用中的对象数 unsigned int free; // 空闲对象数 };第三层per-CPU缓存 — 无锁快速路径SLUB当前默认实现在每个CPU上维护一个本地对象池struct kmem_cache_cpu { void **freelist; // 空闲对象链表 struct page *page; // 当前活跃的slab页 int node; // NUMA节点 unsigned int offset;// 对象在页内的偏移 };分配路径非常简洁// mm/slub.c (简化) static void *slab_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) { struct kmem_cache_cpu *c raw_cpu_ptr(s-cpu_slab); // 快速路径从per-CPU freelist取 void *object c-freelist; if (likely(object)) { c-freelist get_freepointer(s, object); return object; } // 慢速路径需要从partial/新页面获取 object __slab_alloc(s, gfpflags, node, c); return object; }四、实践中的典型问题与诊断问题一内存碎片导致高阶分配失败症状系统有大量空闲内存但order3的分配持续失败。诊断工具# 查看各order的空闲块统计 cat /proc/buddyinfo # 输出示例 # Node 0, zone Normal 1024 512 256 128 64 32 16 8 4 2 1 # order0 ... order10如果高阶区order3的数字很小触发内存规整echo 1 /proc/sys/vm/compact_memory或增加vm.min_free_kbytessysctl -w vm.min_free_kbytes65536问题二Slab缓存膨胀# 查看slab缓存统计 cat /proc/slabinfo # 重点关注active_objs / num_objs比值 # 比值 1 表示大量空闲对象浪费内存清理slab缓存echo 2 /proc/sys/vm/drop_caches # 回收dentry和inode五、总结核心技术提炼伙伴系统的本质以2的幂次组织页面通过分裂/合并实现高效物理页分配。关键参数MAX_ORDER决定最大连续分配大小。MIGRATE_TYPES的反碎片策略将页面按可迁移性分类避免不可移动页阻断大块连续分配。实战中通过/proc/pagetypeinfo检查迁移类型分布。Slab的三层架构kmem_cache(类型) → slab(页面) → per-CPU freelist(无锁)。SLUB是当前默认实现用freelist指针链取代位图。分配路径的两阶段快速路径走per-CPU freelist无锁慢速路径走partial slab→新页分配。性能瓶颈通常在伙伴系统层的zone-lock争用。诊断工具链/proc/buddyinfo碎片、/proc/slabinfo缓存膨胀、/proc/pagetypeinfo迁移类型分布。三者结合可以定位90%的内存分配问题。

相关新闻

Sunshine游戏串流服务器:5个关键问题与终极解决方案

Sunshine游戏串流服务器:5个关键问题与终极解决方案

Sunshine游戏串流服务器:5个关键问题与终极解决方案 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾梦想在任何设备上流畅玩PC游戏,却苦于硬件限制…

2026/10/18 8:45:18 阅读更多 →
从裸机到Linux的架构演进路径:什么时候该升级系统复杂度的决策框架

从裸机到Linux的架构演进路径:什么时候该升级系统复杂度的决策框架

从裸机到Linux的架构演进路径:什么时候该升级系统复杂度的决策框架 一、背景与动机 嵌入式项目的架构演进有一个关键决策点:什么时候从裸机/RTOS 升级到嵌入式 Linux?这个决策不是"功能越多就用 Linux",而是需要基于一组…

2026/10/18 2:10:35 阅读更多 →
大模型边端化一周年回顾:2026上半年剪枝、量化、蒸馏技术的突破与局限分析

大模型边端化一周年回顾:2026上半年剪枝、量化、蒸馏技术的突破与局限分析

大模型边端化一周年回顾:2026上半年剪枝、量化、蒸馏技术的突破与局限分析 一、背景与动机 2026 年是"大模型边端化"从概念验证走向工程量产的关键一年。上半年,剪枝、量化、蒸馏这三项核心技术都取得了实质突破,但每项突破都伴随着…

2026/10/18 8:46:06 阅读更多 →

最新新闻

2022 年 12 月青少年软编等考 C 语言七级真题解析

2022 年 12 月青少年软编等考 C 语言七级真题解析

目录 T1. 走迷宫 思路分析 T2. 重建二叉树 思路分析 T3. 快速堆猪 思路分析 T4. 表达式 表达式树 表达式求值 思路分析 T1. 走迷宫 题目链接:SOJ D1233 一个迷宫由 R R R 行 C C C 列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。给定一个迷宫,求从…

2026/10/19 1:11:12 阅读更多 →
2022 年 9 月青少年软编等考 C 语言七级真题解析

2022 年 9 月青少年软编等考 C 语言七级真题解析

目录 T1. 二叉树的深度 思路分析 T2. 迷宫 思路分析 T3. Sequence 思路分析 T4. Priority Queue 练习题 思路分析 T1. 二叉树的深度 题目链接:SOJ P5096 给定一棵二叉树,求该二叉树的深度。 二叉树深度定义:从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路…

2026/10/19 1:11:12 阅读更多 →
2022 年 6 月青少年软编等考 C 语言七级真题解析

2022 年 6 月青少年软编等考 C 语言七级真题解析

目录 T1. 有多少种二叉树 思路分析 T2. 城堡问题 思路分析 T3. 快速堆猪 思路分析 T4. 重建二叉树 思路分析 T1. 有多少种二叉树 题目链接:SOJ P1039 输入 n ( 1 < n < 13 ) n\ (1<n<13) n (1<

2026/10/19 1:11:12 阅读更多 →
如何快速部署 Qwen3.5-35B-A3B-singprobe?SGLang/vLLM 流式安全探针5分钟上手教程

如何快速部署 Qwen3.5-35B-A3B-singprobe?SGLang/vLLM 流式安全探针5分钟上手教程

【免费下载链接】Qwen3.5-35B-A3B-singprobe 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/inclusionAI/Qwen3.5-35B-A3B-singprobe 点击查看 免费下载 Qwen3.5-35B-A3B-singprobe&#xff08;SingProbe&#xff09;是构建在 Qwen/Qwen3.5-35B-A3B 之上的流式安全…

2026/10/19 1:11:12 阅读更多 →
2023 年 5 月青少年软编等考 C 语言七级真题解析

2023 年 5 月青少年软编等考 C 语言七级真题解析

目录 T1. 城堡问题 思路分析 T2. Priority Queue 练习题 思路分析 T3. 二叉树的深度 思路分析 T4. 快速堆猪 思路分析 T1. 城堡问题 题目链接:SOJ D1191 1 2 3 4 5 6 7 ############################# 1 # | # | # | | ######---#####---#---####…

2026/10/19 1:11:12 阅读更多 →
基于蒙特卡洛法的电动汽车充电负荷计算与MATLAB仿真实现

基于蒙特卡洛法的电动汽车充电负荷计算与MATLAB仿真实现

简介&#xff1a;基于蒙特卡洛法的电动汽车充电负荷计算MATLAB程序&#xff0c;面向电力系统分析、电动汽车充电负荷预测方向的科研与工程人员&#xff0c;将出行时间、行驶里程、充电模式等不确定因素量化为概率分布&#xff0c;通过反复随机抽样模拟充电行为&#xff0c;以统…

2026/10/19 1:10:12 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介&#xff1a;本资源为电源技术方向的学术研究文档&#xff0c;聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略&#xff0c;面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集&#xff0c;共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →