主题
第五章 内存管理:分页、分段与虚拟内存
1. 为什么需要地址转换
第二章说过,每个进程都以为自己独占一条从 0 开始的内存。这当然是假象——物理内存只有一条,凭什么每个进程都觉得自己从地址 0 开始?
答案:程序里写的地址是逻辑地址(也叫虚拟地址,程序视角的门牌号),真正访问内存时由硬件把它翻译成物理地址(内存条上的真实位置)。这次翻译不是多此一举,它一口气解决三个问题:
- 重定位:程序编译时不知道自己将来被装进内存哪个位置。有了翻译层,程序统一按"从 0 开始"编址,装到哪儿都能跑。
- 保护:每个进程只能通过自己的翻译表访问自己的内存,翻译表里没有的地址一律拦截——进程再嚣张也摸不到别人的数据。
- 共享:想让两个进程共用一段代码(比如同一个库),只需让两张翻译表指向同一块物理内存。
一句话点透:逻辑地址是操作系统发给每个进程的"专属幻觉",翻译由硬件中的内存管理单元 MMU 在每次访存时自动完成。
2. 连续分配与碎片
最朴素的做法:给每个进程分一段连续的物理内存。分法有固定分区(预先切成固定大小的格子)和动态分区(按需切割)。动态分区释放回收后,内存里会留下大小不一的空闲块,于是有了"挑哪块"的策略:
| 策略 | 规则 | 优缺点 |
|---|---|---|
| 首次适应 | 从头找,遇到第一块够大的就用 | 简单,通常综合表现不差;低地址端易碎 |
| 最佳适应 | 挑能装下的最小空闲块 | 听着节省,实际制造大量装不了东西的小碎屑 |
| 最坏适应 | 挑最大的空闲块切 | 剩下的仍较大还能用;但大块很快被消耗殆尽 |
注意反直觉结论:最佳适应不是最佳——它专门产生极小的、几乎无法再利用的空闲碎屑。
2.1 内碎片与外碎片辨析(高频考点)
| 碎片类型 | 定义 | 产生场景 | 白话比喻 |
|---|---|---|---|
| 内碎片 | 分给进程的块内部用不完的部分 | 固定分区、分页 | 4 人开了 6 人包间,空 2 座但别人不能坐 |
| 外碎片 | 空闲区太零散,总量够但没有一块连续的够大 | 动态分区、分段 | 停车场空位总面积够停卡车,可惜全是零散小格 |
记法:分固定大小的都产生内碎片,按需分配连续区域的都产生外碎片。外碎片可用"紧凑"(把进程挪到一起拼出大空闲区)缓解,但搬家开销大。想根治外碎片,就要放弃"连续"这个执念——这就引出了分页。
