Appearance
内存管理基本概念
考情分析
内存管理在 408 真题中累计考查约 134 分(2009-2026),其中基本内存管理约 28 分,虚拟内存管理约 106 分。本文是基础概念篇,属于 🔥🔥 中高频。
程序写好了,怎么放进内存、放在哪里、怎么防止进程之间互相踩踏?这就是内存管理要解决的三个核心问题。
内存管理的功能
| 功能 | 说明 |
|---|---|
| 内存分配与回收 | 为进程分配内存空间,进程结束后回收 |
| 地址转换 | 将逻辑地址转换为物理地址 |
| 内存保护 | 防止进程越界访问其他进程的内存 |
| 内存共享 | 允许多个进程共享同一段内存 |
| 内存扩充 | 通过虚拟内存技术突破物理内存限制 |
逻辑地址与物理地址
| 概念 | 说明 |
|---|---|
| 逻辑地址(虚拟地址) | 程序中使用的地址,从 0 开始编址 |
| 物理地址(绝对地址) | 内存中的实际地址 |
| 地址空间 | 逻辑地址的集合称为逻辑地址空间,物理地址的集合称为物理地址空间 |
程序编译后产生的是逻辑地址,运行时需要转换为物理地址。
地址重定位
将逻辑地址转换为物理地址的过程称为地址重定位(Address Relocation)。可以把它理解为"翻译"——程序说的是自己的门牌号,重定位负责把它翻译成真正的街道地址。
三种装入方式
| 方式 | 转换时机 | 是否可移动 | 说明 |
|---|---|---|---|
| 绝对装入 | 编译时 | 不可 | 编译时就知道物理地址,只适用于单道程序 |
| 静态重定位 | 装入时 | 不可 | 装入内存时将逻辑地址转换为物理地址,之后不能移动 |
| 动态重定位 | 运行时 | 可以 | 通过重定位寄存器在运行时转换,进程可在内存中移动 |
动态重定位
物理地址 = 逻辑地址 + 重定位寄存器(基址寄存器)的值内存保护
防止进程访问不属于自己的内存区域:
方法一:上下限寄存器
- 上限寄存器:记录进程的最大物理地址
- 下限寄存器:记录进程的最小物理地址
- CPU 每次访存时检查:下限 ≤ 物理地址 ≤ 上限
方法二:基址寄存器 + 限长寄存器
- 基址寄存器:进程的起始物理地址
- 限长寄存器:进程的地址空间长度
- CPU 先检查逻辑地址 < 限长,再加上基址得到物理地址
三种链接方式
| 方式 | 说明 |
|---|---|
| 静态链接 | 编译后将所有模块链接成一个完整的可执行文件 |
| 装入时动态链接 | 装入内存时才进行链接 |
| 运行时动态链接 | 运行时遇到未链接的模块才链接(如动态库 .dll/.so) |
内碎片与外碎片
| 类型 | 说明 | 产生原因 |
|---|---|---|
| 内碎片 | 分配给进程但未被使用的空间 | 分配单位大于实际需要(如分页) |
| 外碎片 | 内存中空闲但太小无法利用的区域 | 多次分配回收后产生(如动态分区) |
选择题陷阱集中地
408 在本章的选择题陷阱往往出在"细微定义差",速查一下:
| 题面常见说法 | 是否正确 | 关键 |
|---|---|---|
| 动态重定位必须由硬件支持 | ✓ | 重定位寄存器+加法器是 CPU 自带,软件做不到运行时翻译 |
| 静态重定位下进程在内存中可以移动 | ✗ | 装入时一次性算完物理地址,移动后地址全错 |
| 限长寄存器在基址寄存器之后检查 | ✗ | 先比较"逻辑地址 < 限长"再加基址,先限长后基址 |
| 分页方案不产生外碎片 | ✓ | 页框等大,永远无"碎",但末页未填满 → 内碎片 |
| 分段方案不产生内碎片 | ✓ | 段按实际大小分配,但多次分配回收后 → 外碎片 |
| 段页式既无内碎片又无外碎片 | ✗ | 段内分页 → 仍有内碎片(末页未填满),但外碎片被消除 |
| 静态链接的程序运行时仍依赖外部库 | ✗ | 所有模块已合并到可执行文件 |
| 动态库(.dll/.so)可在多个进程之间共享同一份代码 | ✓ | 这是动态链接的核心收益之一 |
| 内存保护必须每访存一次都检查 | ✓ | 一次都不查就破功,硬件来做开销才小 |
考研高频考点
- 🔥🔥🔥 逻辑地址与物理地址的转换(动态重定位)
- 🔥🔥🔥 内碎片与外碎片的区别
- 🔥🔥 三种装入方式(绝对/静态/动态)
- 🔥🔥 两种内存保护方式
- 🔥 动态重定位的优势(进程可移动)
理解了地址转换和内存保护的基本概念后,下一个问题是:内存空间到底该怎么分给各个进程?下篇来看连续分配的三种策略。