Linux内核页缓存回收机制与内存压力调优方法 - 第2节
2.1 物理内存的层次化组织
现代计算机系统,尤其是服务器和NUMA(Non-Uniform Memory Access,非统一内存访问)架构的机器,物理内存不再是简单的线性数组。Linux内核为了高效管理、回收和调度内存,将物理内存组织为三个层次:节点(Node) → 区域(Zone) → 页(Page)。理解这一层次结构是掌握页缓存回收机制的前提。
核心观点: Linux 内存管理的核心抽象是将物理内存按“访问延迟”和“硬件约束”进行分区。NUMA节点对应CPU与内存的物理距离,Zone对应硬件寻址能力限制,Page则是内核管理的最小单元。
2.1.1 NUMA 架构与内存节点(Node)
在NUMA架构中,CPU访问本地内存(直连内存)的速度远快于访问远程内存(通过互联总线访问其他CPU的内存)。Linux内核将每个CPU及其本地物理内存抽象为一个 内存节点(pg_data_t)。
- 本地内存访问: 延迟低,带宽高。
- 远程内存访问: 延迟高,带宽低,且可能引发互联总线争用。
- 内核策略: 内存分配时优先从当前CPU所在节点分配(本地分配),以提升性能。
性能提示: 在NUMA系统上,如果进程频繁访问远程节点内存,性能会显著下降。使用
numactl 命令可以绑定进程到指定CPU和内存节点,避免跨节点访问。
2.1.2 内存区域(Zone)
每个内存节点内部,根据物理地址范围和硬件限制,进一步划分为多个 区域(Zone)。Linux内核主要使用以下三种区域:
| 区域名称 | 物理地址范围 | 主要用途 | 关键约束 |
|---|---|---|---|
| ZONE_DMA | 0 ~ 16 MB | 老式ISA设备DMA操作 | 地址必须低于16MB,用于兼容旧硬件 |
| ZONE_DMA32 | 0 ~ 4 GB | 32位设备DMA操作 | 地址必须低于4GB,用于现代PCIe设备 |
| ZONE_NORMAL | 16 MB ~ 896 MB (32位) 或 4GB 以上 (64位) |
内核直接映射、常规内存分配 | 内核线性映射区,性能最佳 |
| ZONE_HIGHMEM | > 896 MB (仅32位) | 用户进程页缓存、用户态内存 | 内核不能直接访问,需要临时映射 |
| ZONE_MOVABLE | 可变 | 可迁移页面(防止内存碎片) | 页面可以被迁移,用于内存规整 |
注意: 在64位系统上,由于虚拟地址空间足够大,ZONE_HIGHMEM 已经不再使用。所有物理内存都可以被内核直接映射,因此主要使用 ZONE_DMA、ZONE_DMA32 和 ZONE_NORMAL。
2.1.3 物理页框(Page Frame)
物理内存最终被划分为固定大小的 页框(Page Frame),简称 页(Page)。页是内核内存管理的最小单位。
- 默认大小: 4 KB(x86/ARM 架构)。
- 大页(Huge Page): 2 MB 或 1 GB,用于减少TLB miss,提升大内存应用性能。
- 内核描述: 每个物理页框对应一个
struct page结构体,存储页的状态、引用计数、映射信息等。
关键数据结构:
struct page 是内核中最重要的数据结构之一。它包含了 flags(页状态标志)、_refcount(引用计数)、mapping(指向地址空间的指针)、lru(链表节点,用于页回收)等字段。
// 简化后的 struct page 定义(位于 include/linux/mm_types.h)
struct page {
unsigned long flags; // 页状态标志(如 PG_locked, PG_dirty, PG_uptodate)
atomic_t _refcount; // 引用计数,决定页是否可以被释放
struct address_space *mapping; // 指向该页所属的地址空间(用于文件页缓存)
pgoff_t index; // 在地址空间中的偏移量
struct list_head lru; // LRU链表节点,用于页回收算法
union {
struct {
unsigned long private; // 私有数据
};
struct kmem_cache *slab_cache; // SLAB分配器使用
};
// ... 其他字段
};
2.2 层次关系总结
物理内存管理的三层结构可以总结为以下流程:
- 系统启动时: 内核遍历物理内存,根据NUMA拓扑创建
pg_data_t节点。 - 节点初始化: 每个节点内部,根据物理地址范围划分
zone(DMA、DMA32、NORMAL、MOVABLE)。 - 页框管理: 每个zone管理一个
struct page数组,每个page代表一个4KB物理页框。 - 分配与回收: 内存分配时,内核从当前CPU所在节点的合适zone中分配page;回收时,通过LRU链表遍历page进行回收。
调优关联: 页缓存回收机制的核心操作对象就是 page。回收算法(如LRU)遍历的是每个zone内的 LRU链表,而NUMA节点信息决定了回收时是否优先回收本地内存。理解Node/Zone/Page的层次,是后续学习内存压力调优的基础。