内存管理
这页讲的是:Linux 怎么管理内存,为什么内存不只是“放变量的地方”,还牵涉缓存、映射、回收和系统整体性能。学这页的关键,是把“程序视角的内存”和“内核视角的内存”区分开。
这块是什么
内存管理负责把有限的物理内存组织起来,提供给内核和用户程序使用;同时,它还负责虚拟地址空间、页缓存、回收、交换和内存压力下的系统行为。很多人以为内存管理就是“分配和释放”,其实它更像“资源布局 + 映射 + 缓存 + 回收”的总管。
你可以先把它理解成:内核负责决定“哪些内容放内存里、怎么映射过去、空间不够时怎么腾地方”。
它负责什么
管理物理内存
- 把内存划分为页
- 跟踪哪些页可用
- 把页分配给不同需求
- 尽量让有限内存被合理利用
管理虚拟地址空间
- 给进程提供独立视图
- 把虚拟地址映射到物理页
- 隔离不同进程
- 让程序不用直接面对真实物理布局
管理缓存与回收
- 维护页缓存
- 处理内存压力
- 必要时回收或交换
- 在性能和可用性之间不断做平衡
从程序视角到内核视角
| 视角 | 你平时会怎么想 | 内核实际在做什么 |
|---|
| 程序视角 | 我申请了一块内存,用完再释放。 | 内核要决定这块地址空间怎么映射、背后实际用哪些页、何时真正分配。 |
| 文件访问视角 | 我只是读了一个文件。 | 内核可能先把文件内容放进页缓存,下次再访问就不一定打磁盘。 |
| 系统性能视角 | 机器为什么突然卡顿了? | 可能不是 CPU 不够,而是回收、写回、交换、缺页等内存行为在放大延迟。 |
| 系统稳定性视角 | 为什么明明还有一点空闲,程序还是出问题? | 内核要处理碎片、回收效果、可用页类型和极端压力,而不是只看一个“剩余多少”。 |
关键概念
| 概念 | 现在怎么理解 |
|---|
| 页 | 内核管理内存的基本单位,可以把它看成一块标准尺寸的内存小砖块。 |
| 页表 | 记录虚拟地址和物理内存之间关系的结构。 |
| 页缓存 | 把磁盘文件的内容先缓存到内存里,提高文件 I/O 效率。 |
| slab/slub | 为很多小对象提供高效分配方式的机制。 |
| OOM | 内存实在不够时,系统采取的极端处理策略。 |
为什么重要
- 程序能否稳定运行,和内存管理强相关。
- 文件读写性能,很大程度上受页缓存影响。
- 大量系统“卡顿”或“抖动”现象,本质上都是内存压力的结果。
- 很多你以为是单个程序的问题,实际上是整个系统在内存紧张下做出的全局反应。
内存紧张时大概会发生什么
| 现象 | 内核大概在做什么 | 你现在怎么理解 |
|---|
| 缺页变多 | 访问的内容不在当前可用页里,需要补齐映射或把数据调进来。 | 说明“地址存在”不等于“数据已经在手边”。 |
| 回收变频繁 | 系统试图腾出更多可用页,回收缓存或不活跃内容。 | 这会带来性能代价,尤其在压力持续时更明显。 |
| 开始交换 | 某些不常用页面被挪到交换空间。 | 这是系统在尽量续命,但通常也意味着体验会变差。 |
| 触发 OOM | 回收和交换都无法缓解时,系统进入极端处理。 | 这不是某个函数单独“决定坏掉了”,而是系统级资源耗尽的结果。 |
它不负责什么
- 它不直接决定谁运行,那是调度器的职责。
- 它不定义文件语义,那是 VFS 和文件系统的职责。
- 它不直接决定网络协议,但网络收发会大量消耗和依赖内存。
和其他模块的关系
| 相关模块 | 关系 |
|---|
| 文件系统 | 文件数据经常先进入页缓存,因此两者深度耦合。 |
| 驱动 | 设备常要申请缓冲区、映射内存,尤其是 DMA 场景。 |
| 调度器 | 内存压力会影响任务运行体验,反过来任务行为也影响内存使用模式。 |
| 并发控制 | 内存结构本身也需要安全同步访问。 |
常见误解
- 误解一:内存管理就是 malloc/free。实际上那只是上层最显眼的一小部分。
- 误解二:空闲内存越多越好。实际上 Linux 会积极利用空闲内存做缓存,关键不是“空没空”,而是“需要时能不能及时拿回来”。
- 误解三:OOM 只是某个程序写得不好。很多时候它体现的是系统级压力和全局权衡。
读完这页后,你应该能回答
- 为什么内存管理不只是“分配和释放”?
- 为什么页缓存会让文件系统和内存管理纠缠在一起?
- 为什么系统卡顿现象常常和内存压力有关?
后面适合继续问:虚拟内存到底给了系统什么好处?页缓存为什么既像内存问题又像文件系统问题?OOM 是怎么决定“牺牲谁”的?