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/7/27 11:14:06 阅读更多 →
从裸机到Linux的架构演进路径:什么时候该升级系统复杂度的决策框架

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

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

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

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

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

2026/7/27 11:14:06 阅读更多 →

最新新闻

独立开发者年度趋势判断:AI 工具如何重塑一人公司的技术栈

独立开发者年度趋势判断:AI 工具如何重塑一人公司的技术栈

独立开发者年度趋势判断:AI 工具如何重塑一人公司的技术栈 一、"一人公司"模式的AI化:从理想主义到可行方案 "一人公司"(One-Person Business)在过去三年经历了从浪漫化到务实化的转变。2024 年的叙事是"…

2026/7/27 11:30:11 阅读更多 →
BQ27Z746电量计数据命令全解析:从RSOC读取到MAC配置实战

BQ27Z746电量计数据命令全解析:从RSOC读取到MAC配置实战

1. 项目概述与核心价值 在嵌入式系统和便携式设备开发中,电池管理(BMS)的精准度直接决定了产品的用户体验和可靠性。无论是你手中的智能手机、脚下的电动滑板车,还是路边的储能柜,其“心脏”——电池包——的健康与剩余…

2026/7/27 11:30:11 阅读更多 →
WSABuilds:在Windows上实现完整Android体验的终极解决方案

WSABuilds:在Windows上实现完整Android体验的终极解决方案

WSABuilds:在Windows上实现完整Android体验的终极解决方案 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or KernelSU (root…

2026/7/27 11:30:11 阅读更多 →
网盘直链下载助手:浏览器一键获取真实下载地址的终极指南

网盘直链下载助手:浏览器一键获取真实下载地址的终极指南

网盘直链下载助手:浏览器一键获取真实下载地址的终极指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…

2026/7/27 11:30:11 阅读更多 →
Three.js Web3 可视化避坑:移动端崩溃、内存泄漏与渲染性能的 7 月实战总结

Three.js Web3 可视化避坑:移动端崩溃、内存泄漏与渲染性能的 7 月实战总结

Three.js Web3 可视化避坑:移动端崩溃、内存泄漏与渲染性能的 7 月实战总结 一、引言 7 月 Three.js Web3 可视化项目踩了三个大坑:移动端 WebGL 崩溃、纹理内存泄漏、以及大规模节点渲染的性能瓶颈。每个坑都不是"理论上可能出错"的假设&…

2026/7/27 11:30:11 阅读更多 →
如何用3个简单步骤实现微信聊天记录永久保存与智能分析

如何用3个简单步骤实现微信聊天记录永久保存与智能分析

如何用3个简单步骤实现微信聊天记录永久保存与智能分析 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg …

2026/7/27 11:29:11 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻