放一下存储器管理的笔记把
¶学习目标
Ø能够理解各层存储器的作用
Ø理解存储管理的基本任务
Ø理解逻辑地址、物理地址的概念
Ø理解程序装入的实现方式及特点
Ø理解程序链接的实现方式及特点
¶目标评价
-
说出常见的计算机存储硬件
-
说出存储层次中各硬件的特点
-
分析源程序、目标程序和可执行程序的地址形式
-
理解CPU对内存的访问过程
-
说出程序的装入和链接方式
¶基础概念
¶内存管理的任务
-
内存分配回收
-
地址转换
-
存储扩充
-
存储保护
学后应能够回答的问题

¶存储器的层次结构

¶寄存器
-
存放
CPU执行时的数据和指令
¶高速缓存
介于寄存器和存储器之间
-
备份主存常用数据和指令,减少对主存储器的访问次数
-
缓和内存和处理机之间的矛盾

l1d:一级数据缓存
L1i:一级指令缓存
L2 cache:二级缓存
L3 cache:三级缓存
¶磁盘缓存
-
暂时存放频繁使用的一部分磁盘数据和信息
-
缓和主存和I/O设备在速度上的额不匹配
-
利用主存的部分空间,主存可看成辅存的高速缓存
¶主存
¶性能指标
-
按字节连续编址,没个存储单元为1个字节(8个二进制位)
-
存储容量:所包含的存储单元总数(单位:MB或GB)

简例

¶程序地址
¶程序在成为进程前的准备工作
总结
程序在成为进程前的准备工作
-
编辑:形成源文件(符号地址)
-
编译:形成目标模块(模块内符号地址解析)
-
链接:由多个模块或程序库形成可执行文件(模块间符号地址解析)
-
装入:构造PCB,形成进程(物理地址)
-
编辑:编写源程序
-
编译:由编译程序(Complier)对源程序进行编译,形成若干个目标模块
-
链接:由链接程序(Linker)将目标模块和他们所需要的库函数链接在一起,形成一个完整的装入模块
-
装入:由装入程序(Loader),将装入模块装入内存
就像C语言代码,到运行的过程:
-
编译
-
链接
-
运行
¶程序各阶段的地址变换
-
源程序编译后的main.s

add:符号表示
符号地址
-
源程序汇编后的main.o和test.o反汇编的文件

13:整数值
相对地址
-
可执行程序myprog

4004e2 :整数值
相对地址
-
可执行文件装入内存执行时的地址?
内存单元地址由CPU对内存的访问方式决定
编译、汇编、链接,三个过程的地址变换是编译器做的
而,将生成好的可执行文件,放到内存中运行,是操作系统要考虑的事情
¶物理地址和逻辑地址
¶物理地址(绝对地址)
-
物理内存的地址,内存以字节位单位编址
-
物理地址空间:所有物理地址的集合
¶逻辑地址(虚拟地址、相对地址)
-
由CPU产生的地址,即成程序编译后使用的相对于0字节的地址
-
逻辑地址空间:由程序所生成的所有逻辑地址的集合
¶地址转换(地址重定位、地址映射)
-
程序中的逻辑地址转换为物理地址
地址转换是操作系统内存管理任务之一
¶程序的装入

¶地址转换时期
-
绝对装入方式
- 编译产生的地址使用绝对地址
- 程序或数据被修改时,需要重新编译程序
-
可重定位装入方式
- 编译后的目标模块使用相对地址
- 在装入时,完成重定位(静态重定位)
- 需硬件支持
-
动态运行时装入方式
- 编译后的目标模块使用相对地址
- 在运行时,完成重定位(动态重定位)
¶程序的链接
¶静态链接
-
在程序运行前,将各目标模块及它们所需的库函数链接成一个完整的装配模块
-
对相对地址进行修改;变换外部调用符号
¶装入时动态链接
-
在装入内存时,采用边装入边链接的链接方式
-
便于修改和更新
-
便于实现对目标模块的共享
¶运行时动态链接
-
将某些目标模块的链接推迟到执行时才执行
-
加快装入过程,节省大量的内存空间
对于运行时动态链接,动态链接库像是相关联的东西
动态链接库详细介绍
动态链接库(Dynamic Link Library,简称DLL)是包含可以由多个程序共享使用的代码和数据的文件。这种技术使程序能够高效地复用资源、减少重复代码以及节省内存空间。
各种存储管理方案

学习目标
掌握各种存储管理方案的内存分配回收、数据结构、地址转换、存储保护、主要技术、优缺点
-
能够分析单一分区、固定分区、动态分区的管理方式及优缺点
-
掌握操作系统分区管理的数据结构、分区分配算法、回收算法
-
理解并应用分区管理的地址变换方法
-
掌握分区管理的内存扩充技术:交换、覆盖、紧凑

¶连续分配存储管理方式
连续存储方式:为一个用户程序分配一个连续的内存空间
分类
-
单一连续分区
-
固定连续分区
-
动态分区分配
-
动态可重定位分区分配
¶单一连续分区
¶分配方式
单道程序环境下,仅装有一道用户程序,整个内存的用户空间由该程序独占。
-
内存分配管理非常简单,内存利用率低
-
用于单用户、单任务OS
-
CP/M、MS-DOS、RT11
¶固定分区
¶管理方式
多个分区可装多道程序
分区大小固定
分区个数固定

固定分区中,使用固定分区使用表来管理分区的使用情况。

¶地址重定位与存储保护

-
静态重定位
-
界限寄存器
静态重定位
-
在程序装载时,由操作系统将逻辑地址加上分区的起始地址,转换为物理地址
-
该方法简单,但程序装载后地址固定,无法移动(但固定分区情况下,程序确实不会发生移动)
界限寄存器
-
每一个分区设置一个界限寄存器,记录该分区的最大地址范围。
-
访问内存时,硬件检查物理地址是否在分区范围内,超出范围则触发包含异常。
¶特点
优点:易于实现,开销小
问题:
-
可能存在内碎片和外碎片
NOTE内碎片:占用分区之内未被利用的空间
外碎片:占用分区之间难以利用的空闲分区通常是小的空闲分区
TIP举个例子:
例如,现在操作系统分给的固定分区大小为16k
但是又进程现在申请12k大小的内存,但是由于操作系统为固定分区模式,所以只能给该进程分一个大小为16k的分区,这样就有4k空间被浪费了,这浪费的4K空间称为内碎片
另外,再比如,现在操作系统仅剩下1K的存储空间,所有进程都无法装入,这1K存储空间,就称为内碎片
-
分区数固定,限制了并发执行的程序数目
¶动态分区



¶数据结构



空闲分区链用于高效的管理空闲内存块
看起来,每一个空闲分区中,都会存放下一个空闲分区的首地址
另外,还会存放当前分区的大小
¶分配算法
¶基于顺序搜索的动态分区分配算法
-
依次搜索空闲分区链上的空闲分区,寻找一个大小能够满足要求的分区
-
首次适应算法、循环适应算法、最佳适应算法、最坏适应算法
¶首次适应算法
-
空闲分区链以地址递增的次序链接(注意!这里不是按照空闲分区的大小进行链接)
-
从链首开始顺序查找,直到找到一个大小能够满足要求的空闲分区为止
此处的含义是:当找到一处空闲块,空闲分区的大小大于当前需要装入的进程时,就会将该空闲块中进程所需要的部分 分给进程,剩下的部分仍作为空闲分区
-
缺点:低址部分留下许多小碎片
¶循环首次适应算法
-
从上次找到的空闲分区的下一个空闲分区开始查找,直到找到一个能满足要求的空闲分区
-
空闲分区分布更均匀,减少了查找的开销
-
缺乏大的空闲分区
¶最佳适应算法
-
搜索整个序列,找到适合条件的最小分区进行分配
-
空闲分区按其容量从小到大的顺序链接
-
用最小空间满足要求;但留下许多难以利用的小碎片
¶最坏适应算法
-
搜索整个序列,寻找最大分区进行匹配
-
空闲分区按其容量从大到小的顺序链接
-
分割后空闲块任为较大空块;缺乏大的空闲分区
关于每种分配算法是否会产生 内/外碎片的讨论
首次适应算法
-
不会产生内碎片:因为首次适应算法中,每次分给进程的都是刚好够进程请求的
-
会产生外碎片:因为随着申请的进程数越来越多,空闲块就会被拆的越来越小,直到最后无法分给任何一个进程
循环首次适应
其实和首次适应算法差不多
最佳适应算法
也是动态分区的一种
一般来说,动态分区都是不会产生内碎片的,因为给进程分的,都恰好是进程所需要的
但由于是动态分区,则不可避免空闲块被切的越来越小,直到无法分给任何进程
其实,循环首次适应、最佳适应、最坏适应,都只是对首次适应算法的改进,都只是修改了适应算法,而分配空间的核心相同
¶基于索引搜索的动态分区分配算法
-
提高搜索分区的速度,在大、中型系统中采用
-
快速适应算法、伙伴系统和哈希算法
¶快速适应算法
-
将空闲分区按其容量大小进行分类,具有相同容量的所有空闲分区设有一个空闲分区链表
-
分配时,根据进程长度,从索引表中寻找能容纳它的最小空闲分区链表;从链表取下第一块进行分配
-
特点
- 优点:不分割分区,不产生碎片,查找效率高
- 缺点:分区归还主存时算法复杂,系统开销较大,存在浪费
¶伙伴系统
固定分区方式不够灵活,当进程大小与空闲分区大小不 匹配时,内存空间利用率很低。 动态分区方式算法复杂,回收空闲分区时需要进行分区合并等,系统开销较大。 伙伴系统 (buddy system)是介于固定分区与可变分区之间的动态分区技术。 伙伴:在分配存储块时将一个大的存储块分裂成两个大小相等的小块,这两个小块就称为“伙伴”。
伙伴算法规定,无论已分配分区或空闲分区,其大小均为 $2$ 的 $k$ 次幂,$k$ 为整数,$n <= k <= m$,其中:$2^n$ 表示分配的最小分区大小,$2^m$ 标识分配的最大分区的大小,通常$2^m$ 是整个可分配内存的大小。
在系统运行过程中,由于不断的划分,可能会形成若干个不连续的空闲分区。
内存管理模块保持有多个空闲块链表,空闲块的大小可以为 2,4,8,$2^m$ 字节($m$ 为正整数)
系统初起时,只有一个最大的空闲块(整个内存)。
当一个长度为$n$的进程申请内存时,系统就分给它一个大于或等于所申请尺寸的最小的2的幂次的空闲块。(并没有一定和进程所需内存相同;即,即使进程用不了那么多,操作系统还是会分给它)
伙伴系统的缺点:不能有效的利用内存。进程大小不一定是2的整数被,因此会造成浪费,内碎片严重。
同时也会出现外碎片,因为还是会有进程无法放入较小的分区。
¶内存分配流程

¶内存回收

¶地址转换

¶相关技术
主存不足的存储管理技术
-
内存紧凑
-
交换
-
覆盖
¶分页存储管理


¶分页存储的基本原理
将内存空间分为一个个大小相等的分区(比如:每个分区4KB)
每个分区就是一个“页框”或称“页帧”、“内存块”、“物理块”
每个页框有一个编号,即“页框号”或者“内存块号”、“页帧号”、“物理块号”
页框号从0开始。

¶地址结构
内存地址(逻辑地址)范围(1块大小为1KB)
内存地址结构:
¶页号P
-
12-31位:20位
-
地址空间最多运行有1M($2^{20}$)页
¶位移量W(页内地址)
-
0-11:12位
-
每页大小为4KB($2^{12}$)
对某特定机器,地址结构是一定的。
若给抵挡一个逻辑地址空间中的地址为A,页面的大小为L,则页号P和页内地址d可按下式求得

¶数据结构
-
进程页表:每个进程有一个页表,描述该进程占用的物理页面及逻辑排列顺序;
- 逻辑页号(本进程的地址空间)-> 物理页号(实际内存空间);
-
物理页面表:整个系统有一个物理页面表,描述物理内存空间的分配使用情况
- 数据结构:位示图,空闲分区链表
-
请求表:整个系统有一个请求表,描述系统内各个进程页表的位置和大小,用于地址转换,也可以结合到各进程PCB里
页表不属于进程的地址空间
但每个进程均有一个页表,由操作系统维护。
页表的主要作用是将进程的虚拟地址(Virtual Address)映射到物理地址(Physical Address)。每个进程都有独立的虚拟地址空间,而页表是管理这种虚拟地址空间的关键数据结构。
页表本身存储在内存中,由操作系统维护。它记录了虚拟页面与物理页面之间的映射关系,例如页面是否在内存中、页面权限等。

¶内存有效访问时间EAT


当快表未命中时,根据程序的局部性原理,下一次再次访问的概率会很大,所以需要将缺失的信息写入到块表中,以便下次查询时可以命中。
¶相关技术
¶两级或多级页表



对于该题,通过逻辑地址空间和页大小可以得出
逻辑地址结构即寻址到一个位
逻辑地址共$10 + 16 = 26$位,
则,寻址到一个位需要:$26$位,即逻辑地址长度为$26$
而通过页表项大小和页大小可以算出一个页表可以存下$2^9$个页表,即逻辑地址结构中页号长度为$9$位
页内偏移量长度即页大小$10$位
所以可以推出现在已经用了$10 + 9 = 19$位
则剩下$7$位
全为页目录号长度
则,页目录号包含表项的个数至少为$2^7$
页目录表,指的是一级页表。
包含表项,指的一级页表中的一项。

