操作系统(内存管理)
考点出现次数重要程度建议掌握深度虚拟页式存储管理18次★★★★★必须精通,大题必考TLB与页表访问15次★★★★★必背公式,会算有效访问时间分页地址转换12次★★★★☆掌握页号、页内偏移分解缺页中断处理10次★★★★☆理清流程,理解“为什么缺页?动态内存分配算法7次★★★★伙伴系统+首次/最佳适应分段存储管理6次★★★☆区分段与页,了解段表结构页面置换算法6次★★★☆掌握四种算法特点及区别多级页表
✅ 一、知识点精炼与逻辑重构(便于记忆与理解)
1. 内存管理核心目标
四大功能:分配/回收、地址转换、扩充、共享与保护
| 功能 | 说明 |
|---|---|
| 分配与回收 | 按需分配内存空间,进程结束时释放 |
| 地址转换 | 将逻辑地址 → 物理地址(重定位) |
| 内存扩充 | 利用虚拟存储技术“逻辑上”扩大内存 |
| 共享与保护 | 多个进程可共享代码/数据;防止越界访问 |
2. 核心概念辨析
| 概念 | 含义 | 关键点 |
|---|---|---|
| 逻辑地址 | 程序生成的地址(相对地址) | 由编译器决定,不唯一 |
| 物理地址 | 内存中实际的地址 | 由硬件确定,唯一 |
| 地址重定位 | 从逻辑地址到物理地址的映射过程 | 可在编译时、加载时或运行时完成 |
| 页(Page) | 逻辑空间等分单位(通常4KB) | 固定大小,用于分页 |
| 页框(Frame) | 物理空间等分单位 | 与页大小一致 |
| 段(Segment) | 按程序逻辑划分(如代码段、堆栈段) | 大小可变,非等分 |
🔑 口诀记忆:
- “页等分,段按需”
- “页是机器的,段是人的”
3. 连续分配方式对比表
| 方式 | 特点 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 单一连续分配 | 整个内存给一个程序 | 实现简单 | 资源浪费严重 | 早期单道批处理系统 |
| 固定分区分配 | 内存划分为固定大小分区 | 简单高效 | 内存利用率低,碎片多 | 早期多道系统 |
| 动态分区分配 | 按需动态划分 | 提高利用率 | 产生外部碎片 | 现代操作系统主流方式之一 |
📌 常见动态分区算法比较
| 算法 | 查找策略 | 优缺点 |
|---|---|---|
| 首次适应(First Fit) | 从头开始找第一个满足的块 | 快速,但易产生“头部碎片” |
| 最佳适应(Best Fit) | 找最小合适块 | 减少大块浪费 |
| 最坏适应(Worst Fit) | 找最大空闲块 | 保留大块供后续使用 |
| 临近适应(Next Fit) | 从上次分配位置继续查找 | 减少头部扫描开销 |
⚠️ 注意:最佳适应 ≠ 最好!虽然名字好听,但实际性能差。
4. 非连续分配管理方式对比
| 方式 | 结构 | 优点 | 缺点 | 代表系统 |
|---|---|---|---|---|
| 分页 | 逻辑空间 → 等分页;物理空间 → 等分页框 | 无外部碎片,内部碎片小 | 无法体现程序逻辑结构 | 现代主流(Linux, Windows) |
| 分段 | 逻辑空间 → 按段划分(代码、数据等) | 支持共享/保护,符合程序结构 | 有外部碎片,管理复杂 | 早期系统(如Intel 8086) |
| 段页式 | 先分段,再每段内分页 | 结合两者优点 | 两级查表,开销大 | 高级系统(如某些嵌入式) |
💡 关键公式:地址转换
- 分页:
$$
\text{物理地址} = \text{页框号} \times \text{页大小} + \text{页内偏移}
$$
- 分段:
$$
\text{物理地址} = \text{段基址} + \text{段内偏移}
$$
5. 虚拟存储管理核心机制
✅ 局部性原理(理论基础)
- 时间局部性:刚访问过的指令/数据很可能再次被访问。
- 空间局部性:正在访问的内存附近区域也大概率会被访问。
🎯 应用:支持“按需调入”、“页面置换”。
✅ 虚拟存储器特征
- 请求调入(Demand Paging)
- 置换功能(Swapping)
- 逻辑容量 > 实际物理容量
✅ 缺页中断(Page Fault)
- 触发条件:访问的页面不在内存中
- 处理流程:
- 检测缺页
- 查找外存中的页面
- 选择淘汰页面(根据置换算法)
- 加载新页面进内存
- 更新页表
- 重新执行原指令
❗注意:缺页中断是异常事件,不是普通中断!
6. 页面置换算法详解
| 算法 | 原理 | 是否可实现 | 性能表现 | 实现难度 |
|---|---|---|---|---|
| OPT(Optimal) | 淘汰未来最久不用的页面 | ❌ 不可实现(需要预见未来) | 理论最优 | —— |
| FIFO | 淘汰最早进入内存的页面 | ✅ 可实现 | 效率低,可能出现 Belady 异常 | 极简 |
| LRU | 淘汰最近最久未使用的页面 | ✅ 可实现(需硬件支持或软件模拟) | 接近 OPT,性能优秀 | 中等 |
| CLOCK(时钟) | 循环扫描,淘汰访问位为0的页面 | ✅ 实用 | 近似 LRU,开销小 | 简单实用 |
🔍 重要考点提醒:
- Belady 异常:在 FIFO 算法下,增加页框数反而导致缺页率上升 → 仅出现在 FIFO
- LRU vs CLOCK:CLOCK 是 LRU 的近似,适合硬件实现
7. TLB(Translation Lookaside Buffer)——快表
| 项目 | 内容 |
|---|---|
| 作用 | 缓存页表项,加速地址转换 |
| 访问速度 | 极快(接近寄存器) |
| 命中率 | 一般在 90%~99% 之间 |
| 命中时 | 直接获取页框号,无需查页表 |
| 未命中时 | 需要查页表,更新TLB |
📌 有效访问时间计算公式(必背!)
$$
\text{EAT} = h \cdot t_{TLB} + (1 - h) \cdot (t_{TLB} + t_{memory} + t_{memory})
$$
其中:
- $h$:TLB命中率
- $t_{TLB}$:TLB访问时间(如10ns)
- $t_{memory}$:内存访问时间(如100ns)
👉 例题解析(2009年真题):
若 $h=0.9$,$t_{TLB}=10ns$,$t_{memory}=100ns$
$$
\begin{align*}
\text{EAT} &= 0.9 \times 10 + 0.1 \times (10 + 100 + 100) \
&= 9 + 0.1 \times 210 = 9 + 21 = 30,\text{ns}
\end{align*}
$$
✅ 答案:30纳秒
8. 伙伴系统(Buddy System)——动态内存分配
📌 核心思想
- 内存按 2 的幂次划分(如 2^10 = 1024 字节)
- 分配时找最小能满足需求的块
- 释放时若其“伙伴”也空闲,则合并成更大块
📊 示例分析(2024年真题)
初始空闲块:256KB(= 2^8 KB),请求依次为:64KB、32KB、64KB、32KB
| 请求 | 操作 | 当前状态 |
|---|---|---|
| 64KB | 256KB → 128KB + 128KB;取一个128KB → 再拆为两个64KB → 分配一个64KB | 剩余:128KB(未用)、64KB(未用) |
| 32KB | 64KB → 32KB + 32KB → 分配一个32KB | 剩余:128KB、32KB(未用) |
| 64KB | 128KB → 拆为两个64KB → 分配一个64KB | 剩余:64KB(未用)、32KB |
| 32KB | 32KB 已存在 → 直接分配 | 剩余:64KB |
✅ 最终结果:剩余一块64KB空闲块
⚠️ 注意:只有当两个“伙伴”都空闲时才能合并!
✅ 二、高频考点总结(2009–2026年数据分析)
| 考点 | 出现次数 | 重要程度 | 建议掌握深度 |
|---|---|---|---|
| 虚拟页式存储管理 | 18次 | ★★★★★ | 必须精通,大题必考 |
| TLB与页表访问 | 15次 | ★★★★★ | 必背公式,会算有效访问时间 |
| 分页地址转换 | 12次 | ★★★★☆ | 掌握页号、页内偏移分解 |
| 缺页中断处理 | 10次 | ★★★★☆ | 理清流程,理解“为什么缺页?” |
| 动态内存分配算法 | 7次 | ★★★★ | 伙伴系统+首次/最佳适应 |
| 分段存储管理 | 6次 | ★★★☆ | 区分段与页,了解段表结构 |
| 页面置换算法 | 6次 | ★★★☆ | 掌握四种算法特点及区别 |
| 多级页表 | 3次 | ★★★ | 二级/三级页表结构,地址转换 |
🎯 结论:
- 虚拟页式 + TLB + 地址转换 + 缺页处理 是绝对核心,占总分约 60%+
- 伙伴系统 在近年真题中频繁出现(2024、2025),需重视
✅ 三、典型题目升级解析(强化训练)
🔹 例题1:二级分页地址转换(2013年真题改编)
题目:某系统采用二级分页,虚拟地址格式如下:
- 页目录号:10位
- 页号:10位
- 页内偏移:12位
页目录表基址:
0x1000,虚拟地址:0x00401024求对应的物理地址。
✅ 解析步骤:
-
分解虚拟地址(十六进制转二进制):
0x00401024 = 0000 0000 0100 0000 0001 0000 0010 0100按字段划分:
- 页目录号(10位):
0000000001→1 - 页号(10位):
0000000001→1 - 页内偏移(12位):
000000100100→0x24
- 页目录号(10位):
-
计算页目录表项地址:
$$
\text{页目录表项地址} = \text{页目录基址} + \text{页目录号} \times \text{页表项大小}
$$
假设每个页表项为 4 字节(标准):
$$
= 0x1000 + 1 \times 4 = 0x1004
$$
-
读取页表基址(假设从该地址读出值为
0x2000) -
计算页表项地址:
$$
\text{页表项地址} = 0x2000 + 1 \times 4 = 0x2004
$$
-
读取页框号(假设值为
0x300) -
计算物理地址:
$$
\text{物理地址} = \text{页框号} \times \text{页大小} + \text{页内偏移}
$$
页大小 = $2^{12} = 4096 = 0x1000$
$$
= 0x300 \times 0x1000 + 0x24 = 0x300000 + 0x24 = \boxed{0x300024}
$$
✅ 答案:0x300024
✅ 技巧提示:记住“先找页目录 → 再找页表 → 最后得页框号”
🔹 例题2:三级页表 + TLB + 缺页处理(2025年真题风格)
题目:某系统使用三级页表,每级页表含 1024 项,页大小 4KB。TLB 命中率 95%,访问时间分别为:TLB=10ns,内存=100ns。某次访问发生缺页,需从磁盘读取页面(耗时 10000ns)。求平均访问时间。
✅ 解答:
- 正常访问(无缺页):
$$
\text{EAT}_1 = 0.95 \times (10 + 100) + 0.05 \times (10 + 100 + 100) = 0.95×110 + 0.05×210 = 104.5 + 10.5 = 115,\text{ns}
$$
-
发生缺页时:
- 需要:查页表 ×3 → 3次内存访问 → 3×100 = 300ns
- 再加一次内存访问取数据:100ns
- 加上磁盘读取:10000ns
- 总计:300 + 100 + 10000 = 10400ns
-
综合平均访问时间(设缺页率 $p = 0.01$):
$$
\text{EAT} = (1-p) \times 115 + p \times 10400 = 0.99×115 + 0.01×10400 = 113.85 + 104 = \boxed{217.85},\text{ns}
$$
✅ 答案:约 217.85 纳秒
💡 考点延伸:缺页率越高,平均访问时间越长 → 说明缓存命中率的重要性!
✅ 四、冲刺建议 & 学习策略
| 阶段 | 建议 |
|---|---|
| 第一轮复习 | 理解基本概念,画思维导图,熟记公式 |
| 第二轮刷题 | 重点攻克历年真题,尤其是 2018–2026 年 |
| 第三轮模拟 | 模拟考试环境,限时做题,训练答题节奏 |
| 最后阶段 | 背诵核心公式、算法特点、缺页处理流程 |
📌 必背清单(冲刺必备)
- 地址转换公式(分页、分段)
- 有效访问时间公式(含TLB)
- 四种置换算法特点与区别
- 缺页中断处理流程
- 伙伴系统分配与合并规则
- 多级页表地址转换步骤
✅ 五、结语:致每一位奋斗的你
内存管理虽难,但只要掌握“逻辑清晰 + 公式熟练 + 真题反复练”,就能拿下这块硬骨头。
📌 记住一句话:
“没有永远的碎片,只有不懂的分配;没有完美的算法,只有合适的策略。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)