1、内存基本概念
1.1 主要功能
- 内存空间的分配与回收;
- 地址转换
- 内存保护:使用上下限寄存器或者重定位寄存器和界地址寄存器
- 内存扩充:交换和覆盖
- 内容共享
2、内存的分配与回收
2.1 连续分配方式
连续分配方式是指为一个用户程序分配一个连续的内存空间,连续分配方式主要分为单一连续分配、固定分区分配、动态分区分配。
(1)单一连续分配
优点:简单,无外部碎片,无须进行内存保护(单道程序设计)
缺点:只能用于单用户、单任务,有内部碎片,存储器的利用率低
(2)固定分区分配
优点:简单,无外部碎片,无须进行内存保护(多道程序设计)
缺点:不能实现多进程共享一个主存区,存储器的利用率低
(3)动态分区分配【可变分区分配】
动态连续分配会使内存产生越来越多的内存块,内存的利用率下降,内存块存在于所有分区的外部(外部碎片),动态分区的分配策略:
- 首次适应算法:从链首(排序)开始顺序查找,找到大小能满足要求的第一个空闲分区分配给作业
- 邻近适应算法:由首次适应算法演变而成,不同之处是分配内存时从上次查找结束的位置开始查找
- 最佳适应算法:找到以第一能满足要求且最小的空闲分区分配给作业
- 最坏适应算法:找到以第一能满足要求且最大的空闲分区分配给作业
可通过紧凑技术整理外部碎片
2.2 离散分配方式(页式存储管理)
固定分区会产生内部碎片,动态分区会产生外部碎片,这两种技术对内存的利用率都比较低,为了避免碎片的产生,引入分页的思想。
2.2.1基本分页存储管理
分页管理不会产生外部碎片,但是会产生页内碎片
(1)页面和页面大小
进程中的块称为页或者页面,内存中的块称为页框或页帧,进程在执行时需要申请主存空间,即要为每个页面分配主存中的可用页框。页面大小应该适中(2的整数幂),页面太小会使进程的页面数过多,页表过长,占用大量内存,增加硬件地址转换的开销,降低页面换入/换出的效率;页面过大会使页内碎片增多,降低内存的利用率。
(2)地址结构
逻辑地址构成:
31-12 | 11-0 |
页号P | 页内偏移量W |
(3)页表
记录进程的每个页面所对应的物理块,系统为每个进程建立一张页表,它记录页面在内存中对应的物理块号。可见,页表的作用是实现从页号到物理块号的地址映射。
页表=页号+物理内存的块号
地址=页号+页内偏移量
物理地址 = 物理内存的块号+页内偏移量
逻辑地址A到物理地址E的变换过程:
(4)快表(高速缓冲存储器)
为了加速地址变换的过程,增设一个具有并行查找能力的高速缓冲存储器——快表(相联存储器),用来存放当前访问的若干页表项,对应的主存中的页表称为慢表。
(5)多级页表
页表是保存页面在内存中对应的物理块号(页面由页号和页内偏移量构成),为了压缩页表,我们进行延伸页表的思想,可以得到多级页表,建立多级页表的目的在于建立索引,以便不用浪费主存空间去存储无用的页表项,也不会盲目地顺序式查找页表项。
以二级页表为例:
一级页号 | 二级页号 | 页内偏移量 |
2.2.2基本分段存储管理
分段管理方式的提出则考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要。
(1)分段
31-16 | 15-0 |
段号S | 段内偏移量W |
(2)段表
每个进程都有一张逻辑空间与内存空间映射的段表,段表项记录该段在内存中的始址和长度
逻辑地址A到物理地址E的变换:
2.2.3段页式存储管理
分页存储管理能有效提高内存利用率,分段存储管理能反映程序的逻辑结构并有利于段的共享和保护,将两者结合起来,形成了段页式存储管理方式。
逻辑地址:
段号S | 页号P | 页内偏移量W |
3、虚拟内存
3.1 局部性原理
- 时间局部性:通过将近来使用的指令和数据保存到高速缓冲中,并使用高速缓存的层次结构实现。
- 空间局部性:使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。
虚拟内存技术实际上建立了“内存-外存”的两级存储器结构,利用局部性原理实现高速缓存。
3.2 缺页中断
在请求分页系统中,每当访问的页面不在内存中时,便产生一个缺页中断。缺页中断不同于一般中断来说,区别是
- 在指令执行期间而非一条指令执行完成后产生和处理中断信号,属于内部异常
- 一条指令在执行期间,可能产生多次缺页中断
3.3 页面置换算法
(1)最佳置换算法(OPT)【向后看】
选择被淘汰的页面是以后永不使用的页面,或者是在最长时间内不再被访问的页面,以便保证获得最低的缺页率。
(2)先进先出算法(FIFO)
优先淘汰最早进入内存的页面,即淘汰在内存中驻留时间最久的页面。会产生所分配的物理块数增大而页故障数不减反增的异常现象,称为Belady异常。
(3)最近最久未使用算法(LRU)【向前看】
选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。
(4)时钟置换算法(CLOCK)
- 简单的CLOCK置换算法:为每帧设置一个访问位
- 改进的CLOCK置换算法:为每帧设置一个访问位A,一个修改位M
A=0,M=0:最近未被访问且未被修改,是最佳淘汰页
A=0,M=1:最近未被访问,但已修改,不是很好的淘汰页
A=1,M=0:最近已被访问,未被修改,可能再被访问
A=1,M=1:最近已被访问,已修改,可能再被访问
缺页次数指的是操作系统将页从外存调入内存的次数,而缺页中断次数指的是由于内存块数量的限制,将内存中暂时用不到的页面与外存中需要调入内存的页面交换的次数。
计算内容:
缺页率:缺页次数/总页面次数
置换次数:缺页次数-物理块(进程分配的物理块)
缺页中断的处理流程:
1.硬件陷入内核,在堆栈中保存程序计数器,大多数当前指令的各种状态信息保存在特殊的cpu寄存器中。
2.启动一个汇编例程保存通用寄存器和其他易丢失信息,以免被操作系统破坏。
3.当操作系统发现缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这些信息,如果没有的话操作系统必须检索程序计数器,取出当前指令,分析当前指令正在做什么。
4.一旦知道了发生缺页中断的虚拟地址,操作系统会检查地址是否有效,并检查读写是否与保护权限一致,不过不一致,则向进程发一个信号或者杀死该进程。如果是有效地址并且没有保护错误发生则系统检查是否有空闲页框。如果没有,则执行页面置换算法淘汰页面。
5.如果选择的页框脏了,则将该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程让其他进程运行直到写入磁盘结束。且回写的页框必须标记为忙,以免其他原因被其他进程占用。
6.一旦页框干净后,操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其装入,当页面被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一用户进程运行。
7.当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映他的位置,页框也标记位正常状态。
8.恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。
9.调度引发缺页中断的进程,操作系统返回调用他的汇编例程
10.该例程恢复寄存器和其他状态信息,返回到用户空间继续执行,就好像缺页中断没有发生过
3.4 抖动
在页面置换过程中,频繁页面调度行为称为抖动或颠簸;
抖动原因是系统同时运行的进程太多,而分配给每个进程的物理块太少,不能满足进程正常运行的基本要求,致使每个进程在运行时频繁地出现缺页,必须请求系统将所缺页面调入内存,使得系统排队等待页面调入/调出的进程数目增加,对磁盘的有效访问时间增加,处理机的利用率下降
3.5 工作集
工作集(Denning):一个进程当前正在使用的页面的集合称为工作集
工作集模型目的是减少缺页中断率
4、内存扩充
4.1 交换
交换是将处于等待状态的程序从内存移到外存,把内存空间腾出来,这个过程是换出;把准备好竞争CPU运行的程序从外存到内存,这个过程是换入。
4.2 覆盖
覆盖是把用户空间分为一个固定区和若干覆盖区,将经常活跃的部分放在固定去,其余部分按调用关系分段,将即将访问的段放在覆盖区,其他段放在外存中,在需要调用钱,将其调入覆盖区进行替换。
交换在不同进程(或作业)之间进行,覆盖则用于同一个程序或进程中。