Linux 6.12 内核深度解析:内存回收核心引擎shrink_node1. 📌 技术点速览在 Linux 内存管理系统中,当物理内存紧张、达到或低于特定的水位线(Watermark)时,内核必须启动页面回收(Page Reclaim)机制以释放物理内存。shrink_node函数是整个内存回收子系统的核心控制引擎,属于MemoryManagement (内存管理系统)模块。shrink_node的主要职责是:多维度扫描与回收:针对指定的 NUMA 节点(pg_data_t),遍历并扫描其上的活跃/不活跃 LRU 链表(或 MGLRU 世代),将冷数据页(如文件缓存页、匿名页)回收或交换(Swap)到磁盘。控制组(Cgroup)感知:支持 Memcg(Memory Cgroup)的层次结构回收,确保容器化环境下的内存隔离与公平回收。回写与拥塞控制(Throttling):在回收过程中,与块设备 I/O 子系统协同,监控脏页回写进度。当发现 I/O 压力过大或页面回写速度跟不上回收速度时,主动对回收进程(包括kswapd和直接回收进程)进行限流(Throttle),防止系统陷入 I/O 抖动(Thrashing)和 CPU 暴涨的灾难。2. 🗺️ 软件功能架构图以下架构图展示了shrink_node在MemoryManagement (内存管理系统)中的核心位置,以及它如何跨模块与Cgroups (控制组子系统)、BlockIO (块设备与IO子系统)和Scheduler (进程调度器)进行协同工作。3. 🔍 核心源码硬核解析 (基于 Linux 6.12)在 arm64/x86 架构下,内存回收的核心逻辑均实现在mm/vmscan.c中。以下是shrink_node的核心源码解析,保留了关键的锁、状态判断和限流逻辑。/* * 源码路径: mm/vmscan.c * 核心职责: 针对单个 NUMA 节点进行页面回收,协调 Memcg 遍历、I/O 拥塞控制与限流。 */ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc) { unsigned long nr_reclaimed, nr_scanned, nr_node_reclaimed; struct lruvec *target_lruvec; bool reclaimable = false; /* * 1. MGLRU (Multi-Gen LRU) 快速路径判断 * 如果内核启用了 MGLRU 且当前是根节点回收,则直接走 MGLRU 的回收逻辑。 * MGLRU 极大地减少了传统 LRU 锁竞争,是现代 Linux 内核(特别是高并发、大内存场景)的推荐配置。 */ if (lru_gen_enabled() root_reclaim(sc)) { lru_gen_shrink