Linux 内核内存管理子系统全面解析与体系构建
一、前言: 为什么内存管理是核心知识
内存管理是 Linux 内核最核心也最复杂的子系统之一,其作用包括:
- 为软件提供独立的虚拟内存空间,实现安全隔离
- 分配/回收物理内存资源,维持系统稳定
- 支持不同类型的内存分配器,最优化性能
- 应对内存压力,培育回收策略,防止系统 OOM
对于 Linux 内核/嵌入式/系统级程序员而言,熟悉内存管理系统是基础能力。
二、全局观察:内存管理子系统结构
纵向分层:内存管理三大场景
分层 | 功能 | 关键组件 |
---|---|---|
地址转换机制 | 虚拟地址 → 物理地址 | MMU, 分段+分页, TLB |
物理页级管理 | 分配和回收物理页 | struct page, zone, buddy |
内核对象分配 | 提供高效率小内存块分配 | SLAB/SLUB, kmalloc, vmalloc |
横向分模块:实际功能分布
- 虚拟内存管理 (VMM)
- 分页/页表机制
- 物理内存分配器 (Buddy System)
- 内核小对象分配器 (SLAB)
- 页面回收与 swap 机制
三、核心模块分析
1. 分段 + 分页:地址转换的基石
- 分段(Segmentation):只在 x86 有效,Linux 采用 flat model,基本忽略
- 分页(Paging):进程地址分成页,用页表维护,支持缺页中断、TLB、COW、hugetlb
2. 物理内存管理:Buddy System
- 分配 granularity :页(page)
- 划分为 zone(DMA/Normal/HighMem)
- 通过 free_area 链表管理 2^n 大小页块
- 分裂与合并策略,避免碎片
3. SLAB 分配器:小对象高效分配
- 构成:cache 结构,内部 slab,实际物理 page
- 分配路径:kmalloc → kmem_cache_alloc → slab 内分配
- 支持 slab 装慎化 (object constructor), 并免别重复初始化
- SLUB 是高性能环境下默认分配器
4. 页面回收 & Swap
- 回收模型:后台线程 kswapd + 前端直接回收 direct reclaim
- 培育 LRU 列表:active/inactive 分类,区分文件页和匿名页
- swap 把匿名页写入 swap 分区,重新读取时产生 swapin
- zswap/zram 提供内存压缩缓存,降低 swap IO
- OOM Killer 根据计算的 score 选择被杀死程序
四、怎样建立自己的学习体系
1. 给自己定位和目标
- 对内核加载/进程场景关注:先看 VMM + Buddy
- 对性能有需求:深挑 SLAB/回收
2. 系统学习路线
- 了解 Linux 虚拟内存分配 (mm_struct / vma)
- 缺页处理流程 (do_page_fault -> handle_mm_fault)
- 页表结构 PGD → PTE 分析
- Buddy 分配器:alloc_pages()
- kmalloc 分配路径
- swap / reclaim 进阶分析
3. 配合实操 + 清单
- 观看 /proc/meminfo /proc/slabinfo
- 使用 kmemleak / slabtop 进行分析
- 用 GDB/QEMU 追踪页表处理
- 建立一份居住的进度清单 + 思维图
五、面试角度应对模型
面试常见问题
问题 | 基本回答思路 |
---|---|
Linux 是否使用分段? | 采用 Flat Model,没有分段隔离 |
Buddy 如何合并或分裂页块? | 2^n 分裂,同级 Buddy 合并 |
SLAB 和 Buddy 关系? | SLAB 依赖 Buddy 分配整页,内部再分裂 |
kmalloc 与 vmalloc 区别 | kmalloc 返回连续物理内存,vmalloc 是虚拟连续 |
swap 与 zswap 差别 | swap 是硬盘 IO,zswap 是 RAM 压缩 |
OOM 如何选择杀死进程 | oom_score, memory usage, badness 算法 |
面试要点分析
- 是否掌握核心数据结构 (page/mm_struct/slab cache)
- 是否知道基本处理流程 (缺页、oom、swap)
- 能否用简洁词说清楚动画软件设计者的同理
六、总结:架设体系解阶式学习
- 总观基本组成:分段,分页,物理,SLAB,swap
- 接通内核组件:形成动态场景连接
- 配合清单、思维图、代码进阶
- 最后进入一些特殊场景:NUMA、缓存分析、优化相关
这是一份基于概念 + 结构 + 应用性问题的学习根基,也是深入 Linux Kernel 必经之路。
如果需要,我可以继续给出“面向面试”的项目化问题和标准答案。