“
内存管理是操作系统最复杂也最关键的部分——每一页的分配与回收,都决定着系统的性能与稳定性。
—— Linux 内核研读笔记
在 Linux 系统中,内存管理是内核最为核心和复杂的功能之一。从进程启动时的地址空间分配,到运行时的缺页中断处理,再到内存紧张时的回收与交换,每一个环节都经过了几十年的精雕细琢。
📌 本文看点
02
缺页异常 + 回收:从Demand Paging到kswapd
03
MGLRU + 6.x 改进:多代 LRU 革命
伙伴系统(Buddy System)
伙伴系统是 Linux 内核核心物理内存分配算法。它将物理内存按2ⁿ 阶组织为 11 条空闲链表(0~10 阶,对应 4KB~4MB)。分配时逐级分裂,释放时递归合并buddy 块,有效减缓外部碎片。
阶 0: 4KB 块
阶 1: 8KB 块
阶 2: 16KB 块 ... 阶 10: 4MB 块
「反碎片化的关键是按可移动性分组——不可移动页、可回收页、可移动页各居其所。」
SLUB 分配器
SLUB 是 Linux 内核默认的小对象分配器,管理 kmem_cache 缓存池(task_struct、inode 等)。通过Per-CPU 空闲列表极大减少锁竞争,batch 批量机制进一步降低 zone->lock 争用。
多级页表
x86-64 采用四层分页:PML4 → PDPT → PD → PT,48 位虚拟地址。自 Linux 4.17 起支持五级页表(PML5),扩展到 53 位,支持 128PiB 地址空间。2MB 大页和 1GB 巨页利用同一结构跳过中间层级,显著降低 TLB miss。
「缺页异常是虚拟内存和物理内存之间的桥梁——每一次缺页都是内核在幕后默默完成的内存调度。」
TLB 与缺页异常
TLB 是 CPU 内部的虚实地址映射缓存。多核 TLB shootdown 是扩展性关键瓶颈,PCID为每个进程分配 ID 避免完全刷新。缺页异常(do_page_fault)处理请求调页、写时复制 COW、交换缺页三种类型。
内核将页面分为活跃 / 非活跃两类链表,再细分文件页和匿名页。双时钟算法通过 PG_active 和 PG_referenced 标志区分热页冷页。
守护进程 kswapd 依据三档水位线(min/low/high)决策:触 low 唤醒异步回收,触 min 触发直接回收(Direct Reclaim)阻塞分配路径,是内存压力直接信号。
swappiness(0~100, 默认 60)控制回收倾向。ZRAM 压缩块设备、ZSWAP 内存压缩池是减少磁盘 I/O 的优化技术。
当直接回收也无法释放内存时,内核触发OOM Killer。oom_badness() 根据 RSS、共享内存、页表开销等评分,选择评分最高者杀死。oom_score_adj(-1000~1000)可人为调整。Linux 4.6 的OOM Reaper异步回收被杀进程内存,避免 OOM 路径长时间持锁。
Memory Compaction 将可移动页面迁移到高阶区域,合并出连续大块。分为同步(分配大页失败时)和异步(kcompactd)两种。透明大页 THP 自动合并 512 个 4KB 页为 2MB,但需评估内存膨胀风险,按场景选择 always/madvise/never 模式。
KSM扫描多进程匿名页,将相同内容合并为写保护共享页,适用于虚拟化整合。CMA预留连续内存给 DMA,空闲时可被常规页使用,设备请求时迁移恢复,广泛用于 ARM 嵌入式场景。
NUMA 架构下First-touch 分配将页面分配在首次访问的 CPU 节点。AutoNUMA(3.8+)后台扫描检测跨 NUMA 访问并自动迁移。通过 numactl 设置 MPOL_BIND 或 MPOL_INTERLEAVE 策略,对数据库和 HPC 影响显著。
cgroup 内存控制器是容器化基石。memory.max限制总内存上限,memory.stat提供匿名页、缓存、SLAB、缺页等详尽统计。v2 的 memory.oom_group可在 OOM 时优雅清除整个 cgroup。
💡 关键指标:pgmajfault(主缺页)是磁盘 I/O 硬指标;pgscan_kswapd 反映回收压力;oom_kill 增长是严重事件。
free -h && cat /proc/meminfo
vmstat 1
cat /proc/zoneinfo
slabtop -s c
Linux 4.6 — OOM Reaper
异步回收被杀进程内存,改善 OOM 场景的系统响应性。
Linux 6.1 — MGLRU 正式合入
Google 贡献的多代 LRU 成为页面回收的革命性改进。
「MGLRU 将页面按访问时间分为多代,回收只需从最旧代挑选——无需长链表遍历,这是 LRU 效率的质变。」
传统双链 LRU 在内存压力大时扫描开销极高。MGLRU 将页面分为多代(GEN0 → GEN_MAX-1),每代内含 file 和 anon 页,回收时无需链表遍历,显著降低 kswapd CPU 占用,是 Linux 6.x 最值得关注的内存管理改进。
Linux 内存管理从微秒级的TLB 命中到秒级的OOM killer决策,每个层面都体现了空间与时间、性能与可靠性的精妙平衡。理解这些机制不仅能帮你诊断线上问题,也能让你对操作系统这门"基础设施的艺术"有更深的敬畏。
从 2.6 内核至今,MGLRU、OOM Reaper、五级页表、ZSWAP 等新特性让 Linux 在应对云原生、大数据、AI 训练等现代工作负载时依然充满活力。
理解内存管理,就是理解 Linux 内核的设计哲学。
热衷于分享 Linux 内核与系统编程的深度内容。
如果你觉得今天这篇有收获,欢迎点赞、在看、转发三连,我们下篇见。