📚 内存管理专题:6 篇完整路线图
第一篇:启动阶段的内存布局与临时页表
标题:《内存管理-启动篇:从实模式到分页开启的内存布局》
核心内容:
- BIOS/GRUB 时代的内存布局(1MB 以下区域用途)
- 内核加载地址(1MB 以上)与链接脚本
- 临时页表(Identity Mapping) 的构建与作用
- 如何安全开启分页(CR3 加载 + 刷新 TLB)
- 启动阶段物理内存探测(Multiboot 信息解析)
✅ 解决:"为什么内核要链接在 1MB 以上?"、"分页开启前如何访问高地址?"
第二篇:物理内存管理 —— Buddy 分配器深度解析
标题:《内存管理-物理篇:Buddy 系统 —— 高效管理物理页》
核心内容:
- 物理内存位图(Bitmap)设计
- Buddy 算法:分裂与合并的完整实现
- 多级空闲链表(free_list[0..MAX_ORDER])
- 内存区域(Zone)概念(DMA/Normal/HighMem 简化版)
- 物理内存初始化(bootmem → buddy 迁移)
✅ 解决:"如何分配 4KB/2MB/4MB 物理页?"、"Buddy 如何减少外部碎片?"
第三篇:内核内存管理 —— Slab 分配器与 kmalloc
标题:《内存管理-内核篇:Slab 分配器 —— 高效管理内核小对象》
核心内容:
- 为什么 Buddy 不适合小对象分配?
- Slab 设计:Cache + Slab + Object 三级结构
- 对象构造/析构回调(ctor/dtor)
- 空闲对象内嵌指针(零额外内存开销)
- 实现
kmalloc/kfree接口
✅ 解决:"如何高效分配 task_struct/file/inode?"、"Slab 如何提升 CPU 缓存命中率?"
第四篇:虚拟内存基础 —— 页表与 VMA
标题:《内存管理-虚拟篇 I:页表操作与虚拟内存区域(VMA)》
核心内容:
- x86 页表结构(PDE/PTE)与权限位(R/W, U/S, G)
- 页表操作 API:
map_page/unmap_page/get_phys_addr - VMA(Virtual Memory Area) 设计:描述进程地址空间
- 按需分页(Demand Paging)与 Page Fault 处理
- 进程页目录共享(高半内核映射)
✅ 解决:"如何动态映射虚拟地址?"、"VMA 如何管理堆、栈、mmap 区域?"
第五篇:用户态内存管理 —— malloc 与 mmap
标题:《内存管理-用户篇:从 brk 到 malloc —— 用户态内存分配器》
核心内容:
- brk 系统调用:管理堆顶指针(program break)
- mmap 系统调用:匿名映射与文件映射
- 用户态
malloc实现:- 小内存:
brk扩展堆 + 空闲链表 - 大内存:
mmap匿名映射
- 小内存:
- 内存回收:
free如何合并空闲块? - 与内核交互:
copy_from_user/copy_to_user
✅ 解决:"用户程序如何使用 malloc?"、"brk 和 mmap 有何区别?"
第六篇:高级内存特性 —— CoW、Swapping 与 NUMA
标题:《内存管理-高级篇:写时复制、交换与 NUMA 优化》
核心内容:
- 写时复制(Copy-on-Write, CoW):
fork时共享页 + 只读保护- Page Fault 触发复制
- 交换(Swapping):
- 交换区(Swap Partition)管理
- 页面换入/换出机制
- NUMA 感知分配(可选):
- 本地内存优先
- 节点间内存迁移
- 内存压缩(zswap)简介
✅ 解决:"fork 为何高效?"、"物理内存不足时怎么办?"
🔑 专题设计亮点:
-
严格递进:
启动 → 物理 → 内核 → 虚拟 → 用户 → 高级
每篇都是下一篇的基础,避免知识断层。 -
问题驱动:
每篇开头明确要解决的核心问题(如 "为什么需要 Slab?")。 -
代码实操:
每篇包含关键代码片段(Buddy 分裂、Slab 构造、VMA 查找等)。 -
对比工业级实现:
每篇结尾对比 Linux 实现(如kmallocvsslab/slub)。 -
避坑指南:
强调常见陷阱(如 TLB 刷新、物理/虚拟地址混淆)。