新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux内核内存管理月度总结:伙伴系统到slab的核心机制回顾

发布时间:2026/11/2 18:48:14来源:尧图网络
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%的内存分配问题。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/2 5:53:33

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/2 5:53:30

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/2 5:53:30

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/2 5:53:28

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/2 5:53:27

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/2 5:53:27

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉