如果进程大于内存的容量或内存中同时运行多个进程,使用覆盖和动态加载可以缓解,但是需要程序员的额外工作。
解决办法:
从物理上扩充内存容量
从逻辑上扩充内存容量
常规存储器的特征
一次性: 作业在运行前需要一次性的全部装入内存
驻留性:作业装入内存后,便一直驻留在内存中,直到作业结束。
正是由于一次性和驻留性,使得程序中暂时不用的数据占用了大量的内存空间,从而需要运行的作业无法装入内存。
在一段时间内,程序的执行仅局限于某个部分;相应地,它所访问的存储空间也局限于某个区域内。
程序在执行时,除了少部分的转移和过程调用指令外,大多数仍是顺序执行的。
子程序调用将会使程序的执行由一部分内存区域转至另一部分区域
程序中存在许多循环结构,循环体中的指令被多次执行。
程序中还包括许多对数据结构的处理,如对连续的存储空间——数组的访问,往往局限于很小的范围内。
局部性表现为:
如果程序中的某条指令一旦执行,则不久的将来该指令可能再次被执行;
如果某个存储单元被访问,则不久以后该存储单元可能再次被访问。
产生时间局限性的典型原因是在程序中存在着大量的循环操作。
一旦程序访问了某个存储单元,则在不久的将来,其附近的存储单元也最有可能被访问。 即程序在一段时间内所访问的地址,可能集中在一定的范围内,其典型原因是程序是顺序执行的。
虚拟内存是一种允许进程部分装入内存就可以执行的技术
局部性原理 : 时间局部性,空间局部性
只有运行的部分程序需要在内存中
逻辑地址空间能够比物理地址空间大
必须允许页面能够被换入和换出
请求页式
在基本分页的基础上,增加了请求调页和页面置换功能后形成的页式虚拟存储系统。
需要硬件和软件支持。
请求段式
离散性:在内存分配时采用离散的分配方式,是虚拟存储器的最基本的特征。
多次性:一个作业被分成多次调入内存运行,即在作业运行时没有必要将其全部装入,只须将当前要运行的那部分程序和数据装入内存即可。是虚拟存储器最重要的特征。
对换性:作业运行过程中信息在内存和外存的对换区之间换进、换出。
虚拟性:从逻辑上扩充内存容量,使用户所看到的内存容量远大于实际内存容量。
可在较小的可用内存中执行较大的用户程序
可在内存中容纳更多程序并发执行
简化了编程操作, 不影响编程时的程序结构(与覆盖技术比较)
提供给用户可用的虚拟内存空间通常大于物理内存(real memory)
❓程序部分运行可以吗?
取页–将所需的部分装入内存
❓发现程序不在内存时,如何将其装入后继续运行?
请求调页—缺页时,产生缺页中断,将外存上的页调入内存
❓ 内存无空间时怎么办?
页面置换(换的不是一个进程,而是一个页)–内存不足时,将哪些页换出内存
主动的页面调入策略,即把那些预计很快会被访问的程序或数据所在的页面,预先调入内存。
预测的准确率不高(50%),主要用于进程的首次调入。也有的系统将预调页策略用于请求调页
当进程在运行中发生缺页时,由系统将缺页调入内存。
目前虚拟存储器系统大多采用此策略。
在调页时须花费较大的系统开销,如需频繁启动磁盘I/O。
❓从何处调入页面
在虚拟存储系统中,外存(硬盘)被分成两部分:文件区和对换区。对换区(连续分配)的磁盘I/O速度比文件区(离散分配)要高。
1️⃣ 从文件系统中调入页面
2️⃣ 从交换区中调入页面
请求分页中的硬件支持
可以说:请求分页=基本分页+请求调页功能+页面置换功能
1)页表机制
状态位(存在位P):用于指示该页是否已调入内存,供程序访问时参考。
访问字段A:用于记录本页在一段时间内被访问的次数,或最近已有多长时间未被访问,提供给置换算法选择换出页面时参考。
修改位M:表示该页在调入内存后是否被修改过。由于内存中的每一页都在外存上保留一份副本,因此,若未被修改,在置换该页时就不需将该页写回到外存上,以减少系统的开销和启动磁盘的次数;若已被修改,则必须将该页重写到外存上,以保证外存中所保留的始终是最新副本。—>提高性能
外存地址:用于指出该页在外存上的地址,通常是物理块号,供调入该页时使用。
2)缺页中断机制
请求分页系统中,每当所要访问的页面不在内存时,便要产生一缺页中断,请求OS将所缺页调入内存。与一般中断的主要区别在于:
缺页中断在指令执行期间产生和处理中断信号,而一般中断在一条指令执行完后检查和处理中断信号。
缺页中断返回到该指令的开始重新执行该指令,而一般中断返回到该指令的下一条指令执行。
一条指令在执行期间,可能产生多次缺页中断。
3)地址变换机制
在每一个页表的表项有一个有效- 无效位相关联,1表示在内存,0表示不内存
1️⃣ 查找页表来确定此次地址访问是否合法
2️⃣ 如果不合法,则中止该进程; 否则如果有效但不在内存,即发生了缺页,则需要将其调入内存
3️⃣ 所需页在外存,找到该页
4️⃣ 找到一个空闲物理块,启动磁盘,把该页读入内存
5️⃣读磁盘结束后,修改页表以指出该页已在内存中
6️⃣ 重新开始执行刚才发生缺页中断的指令,这时它可以访问刚才调入的页
主要的动作:
处理缺页中断
从磁盘读入所需的页——最大的时间开销
重新开始被中断的进程
假定作业Ji共有m页,系统分配给它的主存块为n块,这里m>n。
如果作业Ji执行过程中总的内存访问次数为A, 成功访问的次数为S,不成功的访问次数为F(产生缺页中断的次数),则:
A=S+F
缺页率: p=F/A
找到内存中没有真正使用的一些页,换出
需要找出一个缺页数最少的算法
如果没有空闲帧,需要两个页面传输,一个换出,一个换入。可以通过修改位来降低额外开销。置换实现了逻辑内存和物理内存的划分—在一个较小的物理内存基础之上可以提供一个大的虚拟内存.
通过运行一个内存访问的特殊序列(访问序列),计算这个序列的缺页次数
访问序列是
1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5
7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1
被置换的页将是之后最长时间不被使用的页
实际过程中无法得到以后会引用的所有页面的信息,因此无法实现
FIFO算法可能会产生Belady异常,就是更多的页框相反会产生更多的缺页
使用离过去最近的情况作为不远将来的近似,可以选择最近最少使用的页进行置换。
LRU选择最长时间没有使用的页。
最接近OPT
实现该算法需要硬件支持,记录物理帧的使用情况,需要使用到计数器或者栈
每一个页表项 有一个计数器,每次页通过这个表项被访问,把记录拷贝到计数器中\当一个页需要置换时,查看计数器来决定置换哪一个页
没有足够的硬件支持的话,可以使用该算法
访问位:每个位都与一个位相关联,初始值为0,当页是访问页时设置为1
二次机会(clock)
如果将要(以顺时针)交换某页的访问位是1,则
把访问位设为0
把页留在内存中
以同样的规则,替换下一个页
增强的二次访问
不仅考虑页面的使用情况,还考虑置换代价
选择淘汰页面时,既要是未被访问的,还要是未被修改的页面。
实现:设置两位
访问位(A), 修改位(M)
启动一个进程时,A、M置0
A被定期清零
内存中的所有页面被分成为四类:
第0类:无访问,无修改(A=0,M=0)
第1类:无访问,有修改(A=0,M=1)
第2类:有访问,无修改(A=1,M=0)
第3类:有访问,有修改(A=1,M=1)
OS首先寻找第0类页面,将找到的第一个页面淘汰;
若没找到,则找第1类页面,将找到的第一个页面淘汰,并将扫描过的页面的A位全部置为0;
若没找到,则指针回到开始位置,将所有的A位置为0。然后重复第一步。
LFU :最少使用算法:置换计数器值最小的一个页,即访问次数最少的页
MFU :最常使用算法,认为:最小计数的页也许刚刚被换入和使用,所以置换计数器值最大的页
如何给进程分配一定的空闲内存?
最少页数
保证进程正常运行所需的最小物理块数
若系统为某进程所分配的物理块数少于此值时,进程将无法正常运行(频繁发生缺页)
这个数目取决于指令的格式、功能和寻址方式。
分配策略
平均分配
100个帧,5个进程,每个进程20个帧
按比例分配
根据每个进程的大小来分配
优先分配
根据优先级分配
有空闲帧时可以从空闲帧链表中选择一个帧分配,当没有空闲帧可用时,从哪里分配帧?
全局替换
进程在所有的页中选择一个替换页面;一个进程可以从另一个进程中获得页面
局部替换
每个进程只从属于它自己的页中选择
局部置换时,分配给每个进程的帧的数量不变
全局置换时,进程的帧数量会增加,但是无法控制页错误率
相对而言,全局替换会带来较高的系统吞吐率
固定分配+局部替换
可变分配+全局替换
可变分配+局部替换
如果进程分配到的帧数量小于计算机体系结构所要求的最小数量,那么必须暂停进行执行。并将其置换出去,使其所有分配帧空闲。
为什么?
如果进程没有这些必需的帧,那么很快会出现缺页,此时需置换某个页,然而,其所有页都在使用,置换出去的页立刻又需要置换进来,因此,会不断的产生缺页。
这种频繁的调页行为称作颠簸,也叫抖动。
一个进程的页面经常换入换出,花在换页上的时间要大于进程执行时间
抖动:刚被换出的页很快又被访问,需重新调入,导致系统频繁地交换页面,以致大部分CPU时间花费在完成页面置换的工作上。这样会造成CPU利用率低下
全局置换会造成颠簸,局部置换能限制系统颠簸,但是也会增加进程的有效访问时间,因此应该给进程足够的帧以防止颠簸
局部性假设
工作集理论是在1968年由Denning提出来的。它正是基于局部的假设。
基本思想:
根据程序的局部性原理,进程在一段时间内总是集中访问一些页面(活跃页面).
如果分配给一个进程的物理块数太少了,使该进程的活跃页面不能全部装入内存,则进程在运行过程中将频繁发生缺页
如果能为进程提供与活跃页面数相等的物理块数,则可减少缺页中断次数
工作集窗口(Δ)是指对于给定的访问序列选取定长的区间,落在工作集窗口中的页面集合称为工作集
正确选择工作集窗口(Δ)的大小,对存储器的有效利用和系统吞吐量的提高,都将产生重要的影响。
工作集合精确度与Δ的选择有关。
如果Δ 太小,则不能包含整个局部
如果Δ 太大,则可能包含多个局部
如果Δ 为无限大,则工作集合就是进程执行所需的所有页的集合
具体实现:
OS跟踪每个进程的工作集,并为其分配大于其工作集的物理块数。
如果还有空闲物理块,则可启动另外的进程。
如果所有进程的工作集之和超过了可用物理块的总数,则OS会选择暂停一个进程,该进程被换出,所释放的物理块可分配给其他进程。
其困难在于如何跟踪工作集合(一般采用定时器中断和引用位实现)
工作集理论可用于预调页,用于防止颠簸,但不够灵活
一种更加直接的防止颠簸的方法是控制缺页频率( Page-Fault Frequency ):
颠簸具有较高的缺页率,所以通过控制缺页频率,可以有效地防止颠簸的发生。
如果缺页率太低,回收一些进程的页框
如果缺页率太高,就分给进程一些页框
目前页大小由系统决定
页面大,则内碎片大
页面小,则页表占用的空间大
I/O overhead(I/O开销)磁盘I/O时间中传输时间和数据量有关系,但它占的比例很小,而寻道时间和旋转延迟时间占了很大的比例。所以页面尺寸比较大会有利于减少磁盘I/O时间。
减少I/O及内存的占用:要求页面尺寸小 ,采用小页,总的I/O就会降低,因为小页能够更精确的匹配局部
减少缺页率:要求页面尺寸大
总的趋势:页面尺寸越来越大,这是由于CPU速度和内存容量的增长超过了磁盘速度的加快
I/O互锁
在请求页面调度时,允许某些页锁在内存中
当用户内存有I/O操作时