1. 内存覆盖和交换
-
覆盖技术
- 思想:将程序分为多个代码模块,常用的常驻内存,不常用的随用随调
- 一个固定区:存放最活跃的程序段,调入后不再调出
- 若干覆盖区:不可能同时访被访问程序段可共享一个覆盖区,随用随调
- 缺点:对用户不透明,增加编程负担
-
交换技术
- 思想:内存空间紧张时,系统将内存中某些进程暂时调出外存,把外存中某些已具备运行条件的进程换入内存
- 磁盘分为文件区(离散存储)和对换区(连续存储),换出的进程放在对换区
-
区别
- 覆盖是在同一个程序或进程中的
- 交换是不同进程(或作业)之间的
2. 内存空间的分配与回收
-
连续分配管理方式
-
连续分配:指为用户进程分配的必须是一个连续的内存空间
-
内部碎片:分配给某进程的内部区域中,如果部分没有用上
-
外部碎片:指内存中的某些空闲分区由于太小而难以利用
-
单一连续分配
- 内存被分为系统区和用户区
- 系统区通常位于内存地址部分,用于存放操作系统相关数据;用户区用于存放用户进程相关数据
- 内存中只能有一道用户程序,用户程序独占整个用户区空间
- 优点:实现简单;无外部碎片;可以采用覆盖技术扩充内存,不一定需要采取内存保护
- 缺点:存储器利用率低
-
固定分区分配
- 内存被分为系统区和用户区
- 用户区分为若干个用户分区(分区大小可以相等或者不等)
- 分区大小相等:缺乏灵活性,但是适用于用一台计算机控制多个相同对象的场合
- 分区大小不等:增加灵活性,可以满足不同大小的进程需求
- 通过数据结构——分区说明表记录分区信息,实现分配各个分区的分配与回收。
- 优点:实现简单;无外部碎片
- 缺点:分区大小无法满足用户程序,要采用覆盖技术来解决;会产生内部碎片,内存利用率低
-
动态分区分配
-
内存被分为系统区和用户区
-
用户区不会预先划分内存分区,根据进程的大小动态地建立分区
-
通过数据结构——空闲分区表或者空间分区链记录内存使用的情况
-
通过一定的动态分区分配算法,选出一个分区给作业
-
动态分配算法
- 首次适应算法:每次都从低地址开始查找,找到第一个满足大小的空闲分区;以地址递增的顺序查找空闲分区链(或空闲分区表),找到满足的第一个空闲分区
- 最佳适应算法:尽可能留下大片空闲区,优先使用更小的空闲区;按容量递增的顺序查找空闲分区链(或空闲分区表),找大小能满足要求的第一个空闲分区
- 最大适应算法:优先使用最大的连续空闲分区;按容量递减的顺序查找空闲分区链(或空闲分区表),找大小能满足要求的第一个空闲分区
- 邻近适应算法:每次都从上次查找结束的位置开始查找,找到第一个满足大小的空闲分区,以上次查找结束的位置往够高地址查找空闲分区链(或空闲分区表),找到满足的第一个空闲分区
-
没有内部碎片,但是有外部碎片;外部碎片可用”紧凑“技术来解决
-
-
-
非连续分配管理方式
-
基本分页存储管理方式
-
将内存空间分为一个个大小相等的分区,每个分区就是一个”页帧“,每个页帧都有一个编号,即”页帧号“,从0开始
-
操作系统将进程的逻辑地址空间也分为与页帧大小相等的一个个部分,每个部分被称为”页“和”页面“。每个页面都有一个编号,即”页号“,从0开始
-
操作系统以页帧为单位为各个进程分配内存空间。进程的页面与内存的页帧有一一对应的关系。各个页面不必连续存放,可以放到不相邻的各个页帧中
-
操作系统为每个进程建立一张页表记录进程的每个页面在内存存放的位置,通常存在PCB中,页表记录进程页面和实际存放的页帧之间的映射关系
-
基本地址变换机构
- 借助进程页表将逻辑地址转换为物理地址
- 设置一个页表寄存器(PTR),存放页表在内存中的起始地址F和页表长度M
- 进程未执行时,页表在内存中的起始地址F和页表长度存放在进程控制块(PCB)中,当进程被调度时,操作系统内核会将其放到页表寄存器中
-
页式管理中地址是一维的,只要给出一个逻辑地址,操作系统就可以自动地算出页号、页内偏移量两个部分
-
具有快表的地址变换机构
- 基本地址变换机构的改进版本
- 快表,又称联想寄存器(TLB),是一种访问速度比内存快很多的高速缓存(TLB不是内存),用来存放最近访问的页表项的副本,可以加速地址变换的速度。与此对应,内存中的页表常称为慢表
- TLB只存页表项的副本,普通的Cache中可能会有其他各种数据的副本
- 引入快表后,优先访问快表中的页表的副本,减少内存的访问的次数;快表中没有命中时,就去访问内存中的页表,再把页表的副本存入快表中;部分操作系统支持快慢表同时查询
-
-
基本分段存储管理方式
- 按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名(在低级语言中,程序员使用段名来编程),每段从0开始编址。以段为单位进行分配,每个段在内存中占据连续空间,但各段之间可以不相邻
- 每个进程建立一张映射表,简称“段表”,确保能从物理内存中找到各个逻辑段的存放位置
-
分段、分页管理的对比
- 页是信息的物理单位,分页的主要目的是为了实现离散分配,提高内存利用率。分页仅仅是系统管理上的需要,完全是系统行为,对用户是不可见的
- 段是信息的逻辑单位,分段的主要目的是更好地满足用户需求,一个段通常地包含着一组属于一个逻辑模块的信息。分段对用户是可见的,用户编程时要显式地给出段名
- 页的大小固定且由系统决定,段的长度却不固定的,由用户编写程序时决定的
- 分页的用户进程地址空间是一维的,用一个记忆符即可表示一个地址
- 分段的用户进程地址空间是二维的,需要给出段名和段内地址表示一个地址
- 分段比分页更容易实现信息的共享和保护,不能被修改的代码称为纯代码或可重入代码(不属于临界资源),这样的代码是可以共享的
-
基本段页式管理方式
- 按进程逻辑模块先分段,再将各段分页,将内存空间分为大小相同的内存块
- 每个段对应一个段表项,每个段表项由段号、页表长度、页表存放块号(页表起始地址)组成
- 每个页对应一个页表项,各页表项长度相同,由页号、页面存放内存块号组成
-
3. 虚拟内存
-
传统存储管理方式的特征和缺点
-
特征
- 一次性:作业必须全部装入内存后才能开始运行
- 驻留性:一旦作业被装入内存,就会一直驻留在内存中
-
缺点
- 作业所需内存很大时,无法全部装入内存,导致大作业无法执行
- 当大量作业要求运行时,由于内存无法容纳所有作业,导致多道程序并发度下降
- 内存中驻留大量的数据,浪费宝贵的内存资源
-
-
局部性原理
- 时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问(因为程序中存在的大量循环)
- 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也很有可能被访问(因为很多数据在内存中都是连续存放的,并且程序的指令也是顺序地在内存中存放的)
-
虚拟内存的定义和特征
-
定义
- 基于局部性原理,在程序装入时,可以将程序中很快会用到的部分装入内存,暂时用不到的部分留在外存,让程序开始执行
- 在程序执行过程中,当访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,继续执行程序
- 内存空间不够,操作系统将内存中暂时用不到的信息换出到外存
-
特征
- 多次性:作业运行不需要一次性掉入内存,允许被分成多次调入调出内存
- 对换性:无需一直常驻内存,将作业进行换入换出
- 虚拟性:从逻辑上扩充了内存的容量
-
-
虚拟内存的实现
-
虚拟内存的实现需要建立在离散分配的内存管理方式基础上
-
内存不存在,请求调页或者请求调段;内存空间不足,页面置换或者段置换
-
管理方式
- 请求分页存储管理
- 请求分段存储管理
- 请求段页式存储管理
-
-
请求分页存储管理
-
请求分页存储管理与基本分页存储管理主要区别在于信息在内存中调入调出
-
页表机制
- 状态位,标志是否已调入内存
- 访问字段,记录访问记录,供置换算法选择换出页面时参考
- 修改位,标志页面调入内存是否被修改过
- 外存地址,标志页面在外存中的存放位置
-
缺页中断机构
- 访问的页面不在内存时,产生一个缺页中断,由操作系统的缺页中断处理程序处理中断
- 缺页进程阻塞,放入阻塞队列,调页完成后再将其唤醒,放回就绪队列
- 如果内存中有空闲块,则为进程分配一个空闲块
- 如果内存中没有空闲块,则由页面置换算法选择一个页面淘汰
- 若页面在内存期间被修改过,则将其写回外存,未修改过的页面不用写回外存
- 一条指令在执行期间,可能产生多次缺页中断
-
地址变换机构
- 请求调页
- 页面置换(需要调入页面,但没有空闲内存块时进行)
- 修改请求页表中新增的表项
-
-
页面置换算法
-
最佳置换算法(OPT)
- 每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,保证最低的缺页率
- 实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面,操作系统无法提前预判页面访问序列,因此,最佳置换算法是无法实现的
-
先进先出置换算法(FIFO)
- 每次选择淘汰的页面是最早进入内存的页面
- 实现方法:把调入内存的页面根据调入的先后顺序排成一个队列,需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块
- Belady异常,当为进程分配的物理块数增大时,缺页数不减反增的异常现象
- 只有FIFO算法会产生Belady异常,FIFO算法虽然实现简单,但是与进程实际运行时规律不适应,先进入的页面也有可能最经常被访问,算法性能较差
-
最近最久未使用置换算法(LRU)
- 每次淘汰的页面是最近最久未使用的页面
- 实现方法:赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间t。当需要淘汰一个页面时,选择现有页面t值最大的,即最近最久未使用的页面
- LRU算法实现需要专门的硬件支持,虽然算法性能好(最接近OPT),但是实现困难,开销大
-
时钟置换算法(CLOCK)
- 又称最近未用算法(NRU),淘汰最近没有使用的页面
- 实现方法:为每个页面设置一个访问位,再将内存中的页面都通过链表指针链接成一个循环队列。当需要淘汰一个页面时,只需检查页的访问位
- 简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描(第一轮扫描可能存在所有页面最近都使用过,重置标志位,第二轮再次扫描,一定能扫出最近没有使用的页面)
- 实现简单,算法开销小
-
改进型的时钟置换算法
- 改进点:考虑只有被淘汰的页面被修改过时,才需要写回外存,优先淘汰没有修改过的页面,避免I/O操作
- 实现方法:在时钟置换算法的基础上,添加一个修改位
- 改进型的CLOCK算法选择一个淘汰页面最多会经过四轮扫描
- 实现简单,算法开销小,性能也不错
-
-
页面分配策略
-
驻留集
- 请求分页存储管理中给进程分配的物理块的集合
- 在采用了虚拟存储技术系统中,驻留集大小一般小于进程的总大小
- 驻留集太小,会导致缺页频繁,系统花大量时间处理缺页;驻留集太大,会导致多道程序并发度下降,资源利用率低
- 固定分配,操作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变,即驻留集大小不变
- 可变分配,先为每个进程分配一定数目的物理块,运行期间,可根据情况做适当的变更,即驻留集大小可变
- 局部置换,发生缺页时只能选进程自己的物理块进行置换
- 全局置换,可以将操作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程
-
工作集
- 在某段时间间隔里,进程实际访问页面的集合
- 一般情况,驻留集大小不能小于工作集大小,否则进程运行过程中将频繁缺页
-
调入页面
- 预调页策略,一般用于进程运行前
- 请求调页策略,进程运行时,发起缺页再调页
-
调页位置
- 对换区,采用连续存储方式,速度更快
- 文件区,采用离散存储方式,速度更慢
- 对换区足够大,运行将数据从文件区复制到对换区,之后所有的页面调入,调出都是在内存与对换区之间进行
- 对换区不够大,不会修改的数据每次都从文件区调入;会修改的数据调出到对换区,需要时再从对换区调入
- UNIX方式,第一次使用的页面都从文件区调入;调出的页面都写回对换区,再次使用时从对换区调入
-
抖动(颠簸)现象
- 页面频繁换入换出的现象,主要原因是分配给进程的物理块不够
-
4. 总结
- 重点:基本分页与基本分段管理
- 重点:虚拟内存的定义
- 重点:页面置换算法
- 请各位大佬发现错误,能指导菜鸟小弟
- 菜鸟也想努力进大厂,加油