目录
7.1 内存管理的功能
7.1.1 内存分配
7.1.2 地址转换
1. 空间的概念
2. 地址转换
7.1.3 存储保护
7.1.4 存储共享
7.1.5 存储扩充
7.2 程序的链接和加载
7.2.1 程序的链接
链接的分类
7.2.2 程序的加载
1. 加载器的功能
2. 装入方式分类
7.3 连续分配方式
7.3.1 单一连续分配
7.3.2 固定分区分配
1. 特点
2. 划分固定分区的两种方法
3. 内存管理
4. 分配策略
7.3.3 动态分区分配
1. 特点
2. 内存管理
3. 分配策略
首次适应算法
下次适应算法
最佳适应算法
最坏适应算法
7.3.4 可重定位分区分配
1. 内存紧凑
2. 重定位
7.3.5 交换和覆盖
7.4 基本分页分配方式
7.4.1 页面与页表
1. 页面相关概念
2. 页表文件
3. 地址结构
4. 逻辑地址分析
7.4.2 地址变换机构
1. 基本地址变换的步骤
2. 分页存储管理造成的资源消耗
3. 快表
4. 多级页表
例题1
例题2
7.5 基本分段分配方式
7.5.1 段表
1. 分段管理逻辑地址结构
2. 段表
7.5.2 地址变换机构
7.5.3 共享与保护
分页与分段的区别
课后测习题解析
内存分配的3种基本形式:
地址空间:程序编译后,设置其地址从0开始,称为逻辑地址,逻辑地址的集合为地址空间。
存储空间:程序在主存中的实际位置称为物理地址,物理地址的集合为存储空间。
对于地址空间和存储空间,有2点需要注意:
例题:在一台电脑上安装了32位的操作系统,配置1GB的内存,问物理地址和逻辑地址最大分别是多少?
答:物理地址最大是2^30,逻辑地址最大是2^32。
地址转换是作业逻辑地址到物理地址的转换,又称为重定位。
地址保护:一个进程不能转移到另一个进程地址上去执行。
权限保护:对于不同的进程有不同的存取权限,确保不能越权执行/访问。
若多进程执行同一个程序,有两种考虑:
请求调入功能:把程序的一部分装入内存,使其先运行,在运行的过程中随时请求操作系统把需要的部分调入内存。
置换功能:把不需要的部分换出主存,以装载需要的部分。
记住四个步骤:编译、链接、加载、运行;
链接后形成逻辑地址,加载后形成物理地址。
链接:由链接程序将编译后形成的一组目标模块和所需的库函数链接在一起,形成一个完整的装入模块。
加载器的功能就是给程序的指令和数据分配物理地址,所以加载又称为装入,加载器又称为装入程序。
加载可以在程序生命周期的不同时刻发生,包括程序的开发、编译、加载和运行:
连续分配就是为一个用户程序划分连续的内存空间。
将内存分为两部分即可,因为单一连续分配只能运行一个用户程序:
使用内存分配表来表示,例如:
分区号 |
起始地址(K) |
大小(KB) |
状态 |
进程名 |
1 |
100 |
100 |
已分配 |
P2 |
2 |
200 |
200 |
已分配 |
P8 |
3 |
400 |
300 |
未分配 |
|
4 |
700 |
100 |
已分配 |
P12 |
这样做的优点是简单,缺点是内存利用率不高。
如果有多个输入队列,则为每个队列分配一个分区;如果只有单个输入队列,就为这个队列中的各个进程分配不同的分区。
一般会提供一个申请和释放的活动队列,顺着队列进行动态分配即可。
有两种形式,空闲分区表和空闲分区链,一般用的是表。
空闲分区表的格式如下:
起始地址 | 大小 |
…… | …… |
对于首次适应算法,空闲分区表从上到下应当按照空闲分区的起始地址从小到大填入;
对于最佳适应算法,则应当按照空闲分区的大小从小到大依次填入。
算是这几个里面性能最好的了,找到第一个能放下的空闲分区就直接放进去:
又叫循环首次适应算法,每次在上一次放进的空闲分区的下一个分区开始查找放得下的分区,查找到最后一个完后回到开头继续找,所以叫循环,如下:
每次寻找和进程大小最相近且放得下进程的空闲分区:
和最佳相反,每次把进程放到可以放得下的最大的空闲分区里:
将离散的分区合并成一个大分区:
交换:把内存中暂时不用的程序和数据换出到外存,以释放内存空间,当换到外存的数再次使用时,再把它们换入内存,主要用于用户管理。
覆盖:将程序划分成若干个功能相对独立的程序段,按照其自身的逻辑结构将那些不会同时执行的程序段共享同一块内存区域,主要用于系统本身。
分区分配主要的缺点是:
用来保存正在运行进程的页表的子集,便于快速对表进行地址转换。
以二级页表为例,逻辑地址包括:外层页号、内层页号和页内偏移量。
页面大小为4KB,一个块号需要4B。
思路为:
页数 = 文件大小 x 页面大小
页表文件大小 = 页数 x 一个块号所需内存
页表文件页数 = 页表文件大小 / 页面大小 (向上取整)
1)页的大小是4KB,页表最大占4MB。
2)因为每页占用的空间为4K = 1000H,而且页表中的物理地址是连续的,所以物理地址3为0090 1000H;
因为代码段长度是8KB,从第一题中可以看出,一页是4KB,所以代码占两页;
将代码段的起始逻辑地址 0000 8000H 转换为二进制,即为:
0000 0000 0000 0000 1000 0000 0000 0000H
根据题目,后12位为偏移量,则代码段对应的两个页号为 0000 0008H 和 0000 0009H,
所以8号页就是1号块,9号页就是2号块,
8号页表项物理地址 = 0020 0000H + 8 * 4 = 0020 0020H
9号页表项物理地址 = 0020 0000H + 9 * 4 = 0020 0024H
块号代表真正的物理地址,而一页是4KB,12位,
已知块号1的物理地址是 0090 0000H,因此块号1 = 00900H,块号2 = 00901H
段号 | 段内地址 |
两者都是用来判断是否越界的。
页 | 固定式分区 | 内碎片 | 不可再用 |
段 | 可变式分区 | 外碎片 | 可以再用 |
链接后形成逻辑地址;
编译后形成物理地址。
因为是分区,所以其实就是隔离不同的内存区域,隔离就有边界,因此称为界地址保护。
分页系统的页面是为操作系统所感知的,分段系统的程序段是为用户所感知的。
3次,第一次是根据逻辑地址查询外页表,第二次是根据外页表查询内页表,第三次是根据内页表查询物理地址。
由于页的大小为2^10B,逻辑地址空间大小为2^16B,所以逻辑地址空间实际上为2^26B,因此逻辑地址是26位的;
由页的大小为2^10B,可知页内偏移量为10;
由于页表项的大小为2B,所以每页可以容纳2^9个页号,因此页号长度为9;
因此页目录号长度为7,可以容纳2^7 = 128个表项。
动态重定位是给可以动态分配内存的存储管理方案使用的,易知可变分区、页式和段式都是动态分配内存的,所以固定分区不能用动态重定位。