引入
- 要使虚存比较实用且有效,两方面因素
- 分页或分段的硬件支持
- 操作系统必须有管理页或段在内存和辅存之间移动的软件
1. 内存管理设计的三个基本选择
- 是否使用虚拟技术
- 使用分页还是分段,或二者同用
- 为各种存储管理特征采用的算法
- 属于操作系统软件领域的问题,是本节的主题
2. 操作系统需考虑的策略(软件方面)
为实现虚拟内存,操作系统需要考虑的策略(软件方面)
目标:最大限度地减少页面错误
不存在一种绝对的最佳策略
读取策略:什么时候读取
放置策略:拿了放内存中的哪
置换策略:把哪个页面换出来
驻留集管理:1)给进程分配多少页框 2)置换的时候,属于该进程之外的页框能不能换
清除策略:什么时候写回(辅存)被改过的页
负载控制:内存中能放多少进程
读取策略
决定某页何时进入内存
一、请求调页
仅在引用页面时,才把相应的页面调入内存
- 所以,进程首次启动时,会发生很多缺页中断
- 局部性原则表明,大多数将来访问的页面都是最近读取的页面,一段时间后,缺页中断会降低到很低的水平。
二、预调页
额外读取所缺页面以外的页面
-
需要考虑大多数辅助储设备的特性:寻道、旋转延迟等
- 所以,若进程的页面连续存储在辅存中,则一次读取多个页面会更有效
-
存在的问题:如果额外读取的页面未使用,则低效
-
赌运气,可能做了无用功
-
放置策略
确定进程驻留在内存中的位置
-
对于纯分段系统,它是重要设计内容,如首次匹配、循环匹配等都可以选择
-
对于纯分页或段内分页,它是无关紧要的,因为硬件以相同的效率执行地址转换功能
-
对于非一致存储访问(NUMA,NonUniform Memeory Access, NUMA ),需要自动放置策略
- 非一致存储访问中,系统中有多个处理器(CPU)和多个内存存储区域,可以理解为多核的情况
- 在多核的情况下,每个核访问的内存空间是不一样的。
- 所以放进来的进程要看是在哪个内存中运行
- 自动放置策略可以自动决定将任务分配给哪个处理器,并优化内存访问
置换策略
一、概述
内存空间不够时,由操作系统负责将内存中暂时用不到的信息换出到外存中,这就需要用页面置换策略去决定应该换出哪个页面
- 页面置换涉及的问题:具体淘汰哪个页面用以置换
1.置换策略(Replacement policy)
-
读取新页时,如何选择内存中要淘汰的页面
- 目标:最近最不可能访问的页面
-
置换策略越精细,实现它的硬件和软件开销就越大
因为页面的换入换出需要磁盘I/O,会有较大开销
2. 页框锁定
- 当页框被锁定时,当前存储在该页框中的页面不能被置换
- 操作系统内核和重要的数据结构保存在锁定的页框中
- I/O缓冲区和时间要求严格的区域也可能保存在锁定的页框中
- 通过将锁定位与每个页框相关联来实现锁定
3. 置换算法
-
最佳 (Optimal, OPT)
-
最近最少使用 (Least recently used, LRU)
-
先进先出 (First-in-first-out , FIFO)
-
时钟 (Clock)
评价置换算法的重要指标:
缺页率——给定时间内,发生缺页的次数与访问总次数的比值。 -
几种置换算法比较(固定分配,局部置换)
二、最佳(OPT)
-
置换下次访问距当前时间最长的页面
-
理想算法,缺页率最少
- 因为每次淘汰的页面是以后永不使用或者最后才访问的页面,这样可以保证最低的缺页率
- 主要用来做参照,因为需知未来,而只有进程执行的时候才知道接下来访问的是哪个页面。操作系统无法提前预判页面的访问序列
-
例子:
三、最近最少使用 (LRU)
-
置换内存中最长时间未引用的页面
最长时间未引用
怎么实现- 每页添加最近访问时间戳——开销大
- 建立链表——开销大
-
根据局部性原理,这也是最近最不可能访问的页面
-
例子
四、先进先出 (FIFO)
-
将分配给进程的页框视为循环缓冲区
-
页面以循环方式删除——简单的置换策略
-
置换驻留在内存中时间最长的页面
-
例子
五、时钟 (Clock)
-
每个页框关联一个使用位U(也称访问位)
- U为0说明最近没访问过
- 当页面首次加载到内存中或被引用时,使用位U设置为1
-
用于置换的候选页框集视作一个循环缓冲区
-
发生缺页中断时
-
检查表针指向页面,如果使用位为0,则新页面替换之,表针前移一个位置;
-
如果使用位为1,则**清0,**表针前移一个位置。
-
重复上述过程。
-
-
注意:命中时表针不移动
-
例子
六、改进的Clock
- 简单的时钟置换算法只考虑了最近一个页面是否被访问过。
- 而如果被淘汰的页面没有被修改过,那么它是不用执行I/O操作写回外存。
- 只有被淘汰页面修改过才会被写回外存
- 所以为了避免I/O操作、减小开销,应优先淘汰没有被修改过的页面
(一)概述
-
在Clock算法基础上,优先置换最近未访问、未修改页面
-
每个页框处于下列情形之一(u:使用位/访问位,m:修改位)
- 1类(u=0, m=0):最近未被访问,又未被修改,最佳淘汰页。
- 2类(u=0, m=1):最近未被访问,但已被修改页。
- 3类(u=1, m=0):最近已被访问,但未被修改。
- 4类(u=1, m=1):最近已被访问且被修改,最不应淘汰页。
-
改进型时钟置换算法实现简单,性能比较理想,被广泛采用
(二)算法流程
- 从指针当前位置开始扫描,这次扫描对使用位不作任何修改,选择遇到的第一个页框**(u=0,m=0)** 置换;
- 若第1步失败,重新扫描,选择遇到的第一个**(u=0,m=1)**的页框置换。这一过程中,将使每个扫描过的页框u置0;
- 若第2步失败,则再次重新扫描,重复第1步,并在必要时重复第2步。
淘汰一个页面最多需要进行四轮扫描,因为:
第二轮扫描时,全部的使用位u会被置为1
第三轮扫描(目标是找(0,0))的只能为(0,0)、(0,1)
所以最多在第四轮
七、页缓冲
-
置换的页,如果要写回辅存,代价较大
- 在内存中采用页缓冲,提高了分页性能,并允许使用更简单的页面替换策略
-
置换的页面
- 未修改,放入空闲页链表尾部
- 当置换的页面没有被修改时,意味着它们的内容在内存中和存储介质(比如硬盘)上的内容是一致的,没有发生改变
- 已修改,放入修改页链表尾部
- 未修改,放入空闲页链表尾部
-
置换策略和高速缓存
-
对于较大的高速缓存,替换页会对性能产生影响
理解:如果需要替换的页已经在高速缓存中存在,那么这个高速缓存块以及相应的内存页都会被置为无效,这样就需要从内存中重新加载新的页,可能引起额外的延迟
- 如果选择替换的页在高速缓存中,则该高速缓存块及内存中所对应的页将失效
-
在使用页缓冲的系统中,可以使用页缓冲区中的页放置策略来提高高速缓存性能
- 大多数操作系统通过从页缓冲区中选择任意页框来放置高速缓存中需置换的页
-
驻留集管理
一、页框分配
页框分配,即给每个进程分配多少个页框
- 分配给每个进程的内存越小,可以驻留在内存中的进程越多
- 若一个进程在内存中的页面少,则缺页率相对较高
- 给进程分配的页框数超出一定大小后,由于局部性原理,缺页率下降到稳定水平
1. 固定分配
在内存中为进程提供固定数量的页框
- 发生缺页时,必须替换该进程的其中一个页面
2. 可变分配
允许分配给进程的页框数在进程的生命周期内变化
二、置换范围
- 置换范围,即计划置换的页集局限于产生缺页的进程本身,还是内存内的所有进程
- 置换策略的作用范围分为全局和局部两类。
- 两种类型的策略的实施都是在没有空闲页框时由缺页中断激活。
1. 局部置换
仅在产生缺页中断的进程的驻留页中选择置换对象
2. 全局置换
在整个内存中选择置换对象,只要不是锁定的页,都可以作为候选页
三、组合
补充:关于为什么没有固定分配+全局置换?
- 这是因为全局置换意味着一个进程拥有了物理块量必然会改变,因此不可能是固定分配
1. 固定分配,局部置换
- 需要事先确定分配给一个进程的页框数量
- 如果给进程分配的数量太小,将会产生较高的缺页率
- 如果分配的页框数太多,内存中只能有较少的程序
- 增加了处理器的空闲时间
- 增加了花在交换上(swapping)的时间
2. 可变分配,全局置换
只要缺页就给分配物理块
- 最容易实现的方法,在很多操作系统里采用
- 操作系统维护一个空闲页框列表
- 当缺页中断发生时,操作系统会把一个空闲页框分配给缺页的进程
- 如果没有空闲页框,操作系统必须选择一个内存中的页框(没有锁定,没有被内核占用)作为置换对象
- 如果选择置换对象不当,将容易再次产生缺页中断,使用页缓冲可以缓解这个问题
- 当缺页中断发生时,操作系统会把一个空闲页框分配给缺页的进程
3. 可变分配,局部置换
要根据发生缺页的频率来动态地增加或减少进程的物理块
-
当一个新进程装入内存时,根据应用程序类型、程序请求等标准分配一定数量的页框作为它的驻留集
-
当缺页中断发生时,从进程驻留集中选择一页用于置换(局部置换)
-
不时重新评估进程的页框分配情况,增加或减少分配的页框,以提高整体性能(可变分配)
由此可以引出工作集的概念
工作集的意思就是我们可以去观察一个程序在运行过程中之前的时间间隔中所使用过的页面,去判断接下来使用多少页面才足够
四、工作集
补充:
比较和理解:
驻留集:指请求分页存储管理中给进程分配到内存块的集合(分配的驻留集太少—>频繁缺页;太多—>降低并发度)
工作集:指在某段时间间隔里,进程实际访问页面的集合(它反映了程序当前阶段活跃的内存部分)
驻留集大小一般不能小于工作集大小
(一) 概述
1. 工作集和虚拟时间
- 工作集W(t, Δ ):进程在虚拟时间t的参数为Δ的工作集W(t, Δ ),表示该进程在过去的Δ个虚拟时间单位被访问到的页集合
- 虚拟时间t:用进程访问内存的次数来衡量虚拟时间t,例如进程一系列的内存访问为r(1),r(2),…r(i), r(i)表示第i次对内存页的访问,对应的虚拟时间为1,2,…i。 Δ为给定的虚拟时间窗口大小,如2次访问。
2. 虚拟时间窗口越大,则工作集越大
例子:
3. 固定的Δ ,工作集随时间变化
稳定阶段和快速变化阶段交替出现
(二) 工作集策略
1. 工作集策略
- 根据工作集来决定驻留集的大小
- 周期性的从驻留集中移去不在工作集中的页(近似LRU)
- 只有驻留集包含工作集时,才执行进程
2. 工作集策略实际难以应用
- 工作集大小随时间变化,并且过去不总是预示着未来
- 给每个进程测量工作集不现实(开销大)
- Δ最优值未知,任何情况都会变化(由Δ随时间变化图可知)
3. 近似工作集策略的应用(代表性算法PFF,VSWS)
- 用缺页率指导驻留集
- 缺页率低于某个阈值,减小驻留集
- 缺页率超过某个阈值,增加驻留集
五、平均访问时间
(一)概述
平均访问时间(平均有效访问时间)
1. 计算
若缺页率为p,内存的访问时间为ma,发生缺页时的访问时间为da,则平均访问时间为(1-p)ma+pda
- 由于ma很小(<10ns),因此很低的缺页率也会导致很大的平均访问时间
2. 缺页访问时间构成
- 缺页中断服务时间
- 页面写出时间(若需置换)
- 页面调入时间——20ms(寻道时间+旋转时间+数据传送时间)
- 重新访问内存指令时间
(二)例子
1. 示例1
假设内存的访问时间为10ns,发生缺页的访问时间为21ms,若因为缺页而出现的性能降低不超过10%,则缺页率的最大数值为多少?
性能下降10%时的有效访问时间: (1+10%)*0.01,单位μs
- 0.01us为10ns
而有效访问时间EAT=(1-p)0.01+21000p,单位为us
可列:EAT<=(1+10%)*0.01
解得:p<= 0.000 000 05
可以发现这么小的缺页率都能造成10%的性能下降
2. 示例2
解:
六、例题
解:
清除策略
用于确定何时将修改过的页写回辅存
一、按需清除(Demand cleaning)
也叫请求清除
- 只有当一页被选择用于置换时,才被写回辅存
- 发生缺页中断的进程在接触阻塞前需等待两次页传送:写回修改页+读入新页
二、预清除(Precleaning)
- 将修改的多页在需要使用它们占据页框之前,成批写回辅存
- 预先写回辅存的页,在置换前可能又会被修改,使得预清除的意义不大
- 可能会浪费辅存的传输容量
三、结合页缓冲技术
更好的方法:结合页缓冲技术
- 只清除用于置换的页(非预先清除)
- 通过页缓冲,将置换的页放在已修改表和未修改表中,已修改表中的页可以成批写回辅存
加载控制
- 决定驻留在内存中的进程的数量
- 多道程序度multiprogramming level,也称系统并发度
一、多道程序度对处理器的影响
-
对于有效的内存管理来讲非常重要
-
内存驻留的进程太少,当所有进程阻塞时,大量时间花在交换上
- 另外,进程数较少—>处理器空闲—>利用率低
-
内存驻留的进程太多会导致抖动
- 这样每个进程都会频繁地产生缺页—>可能会导致频繁的页面置换—>消耗了大量的 CPU 时间和 IO 操作—>降低处理器利用率
二、总结——关于抖动(自补)
1. 抖动
即将要用到的块被换出,系统又得很快将它取回,导致页面被频繁地换入换出,缺页率急剧增加
- 进程物理页面太少(驻留集太小),不能包含工作集
- 造成大量缺页,频繁置换,大部分CPU时间用来处理缺页异常(而不是执行指令)
- 进程运行速度太慢
2. 产生抖动的原因
- 随着驻留内存的进程数目增加,分配给每个进程的物理页面数不断减小,缺页率不断上升
——>需要在并发水平和缺页率之间达到一个平衡