虚存的定义:

需要注意的是,此时应该采用了动态链接、动态装入的策略

操作系统负责缺页的处理(换出、换入),对用户而言是透明不可视的


一个容易混淆的点:

虚拟内存实际上并没有拓展物理存储空间的大小,可以见课后的本节小结内的详细解释


对请求分页管理方式的补充:

主要是对最后流程图过程的补充、理解

当产生缺页中断时,操作系统首先会根据页表中的对应地址(此时未调入是外存地址

去将这个块调入,如果内存没满那么就直接调入,内存满了就需要替换

替换后,被替换的就需要从页表中删除或者说修改,需要同时在快表、慢表中修改

替换的块也需要修改,修改慢表中的内容,并加入快表内,然后再通过快表命中访问

对于2、3、4、5没特别可以说的,主要是第一个可以联系计组的Cache写回策略,计组8内


页框、抖动、工作集:

内存分配策略:固定、可变

固定分配:操作系统为每个进程分配一组固定数目的物理块,在进程运行期间不再改变。即驻留集大小不变

可变分配:先为每个进程分配一定数目的物理块,在进程运行期间,可根据情况做适当的增加或减少,即驻留集大小可变

置换策略:全局、局部

局部置换:发生缺页时只能选进程自己的物理块进行置换

全局置换:可以将操作系统保留的空闲物理块分配给缺页进程,也可以将别的进程持有的物理块置换到外存,再分配给缺页进程

具体几种方式的组合建议直接看书,可变分配局部替换可以理解为“缺页率动态调整”

注:

区分“工作集”、“工作窗口”,驻留集需要大于等于工作集,该部分内容有印象即可


调入页面问题:

文件区、对换区看作是外存中两块不同的区域即可,分别存放不同的数据结构

这里是对应对换区的大小足够大的情况下

对第二种情况的一些补充:

不会被修改的文件直接从文件区读入,同时换出时直接扔掉不用管,哪都不必放直接不要

对于可能被修改的部分则换出的时候放在对换区,因为文件区的读写速度更慢

对于第三种策略,简单概括就是:

没有调用过的全都从文件区调入,曾经调入过的从对换区调入

其他进程如果曾经调用过自身要用的东西,那么自己也只需要从对换区调入就行了


修改替换:

如果这页没有修改过,不需要写回磁盘,修改过就一定要写回磁盘(联系对换区

可以结合上面的对换策略思索


页面置换算法:

当内存已满,而又需要从外存调用一块入内存时,就需要调出一块

决定调出哪块就是页面置换算法所研究的


OPT:最佳置换算法

此算法实际上无法实现,当前需要置换出去的是未来不访问或者最久不访问的

简单来说就是会在最久远的未来访问的,把这个替换出去,因为当下暂时还不会使用


先进先出:

单纯的先进先出,就是队列,每次访问不更新其队列内的顺序,只按先后顺序淘汰

可能会产生Belady现象,书上谈的是“堆栈类算法不可能出现Belady”现象,而该是队列


LRU,同计组中的Cache替换策略

每次访问已经在内存中的页面时需要更新其顺序到首位,最简单的方法就是写一遍

写一遍基本就能懂,做一遍就能明白,没法用言语表达


时钟算法:

最麻烦的算法,需要画循环队列,同时模拟更新,仍然建议走一遍



对于之前页表的一些误解补充:

一个进程保持一个页表,这个页表存储了该进程对应存储虚拟地址到实地址的地址映射

只包含了当前所需要的进程的存储单元映射,而不会包含所有外存的映射


内存映射文件第一段补充:

传统文件访问方式,需要程序员显示给定访问函数,通过四个系统调用完成访问

需要显示用读写指针指明当前需要访问哪块区域

移动读写指针、把文件读入内存、把修改过的内容写回内存均需要程序员主动声明

其一开始就把需要用的给映射到了内存中,需要提前想好我要用什么才能用

而内存映射文件是操作系统自动的,把很多程序员需要思考的问题交给了操作系统来处理

采用内存映射文件后

程序员不需要显示给定那么多个访问函数,只需要打开文件、映射文件即可

映射入虚拟空间后,会返回一个指向该虚拟空间的起始指针,需要注意一开始页都是缺页的

这也是书上“不会实际读入文件内容”这一话的含义

当用户采用指针进行访问时(虽然仍然需要指明访问区域,但只需要采用数组型即可

例如A[10]即可完成对某区域的访问或者修改,这都是在内存中进行的

同时把文件读入内存的操作也就变成了操作系统的缺页处理过程,不需要用户来干

在最终结束进程或者关闭进程时,操作系统同样代替用户将修改过的内容写回磁盘内

对于文件共享,比较容易理解直接看书即可


关于地址翻译,直接参考先前计组那边的PPT,即计组3.6节虚拟存储器,含很多例子的

这些例子吃透就足够了


补充:

物理块、驻留集、分配的块数之间的关系和区分

物理块越小,缺页率越高,物理块越大,缺页率也就越小,因为进程大小是不变的

物理块越小,对应的页表项越多,越容易产生缺页问题,反之则不容易产生

驻留集也可以理解为分配给一个进程的物理块数量

一般而言,增加驻留集即分配给进程的物理块数量越多进程缺页率越低

但因为会有不同算法导致的Belady现象类似于FIFO算法的问题,所以不能说增加即降低

但减少驻留集数量,就会导致进程缺页率的上升

具体其实就是要参考最后一节:缺页率的影响因素,要仔细看

抖动就是因为给进程分配的物理块太“少”,而不是太小,导致频繁缺页


工作窗口是过去一段时间的工作序列,其中的页会有访问顺序上的重复

驻留集是工作集的子集,工作集实际上是“过去一段时间内工作序列内访问的页集合”

驻留集内包含的必然是工作集的一部分,因为必然也是过去一段时间内页的集合

无非驻留集不一定能够包含工作集的所有元素


补充:

三种装入方法、三种链接方法、内存管理方法(连续、非连续、虚拟化页式)间的联系

对于单道批程序的话,就是单纯的绝对装入、单一连续分配

此外只有固定分配需要静态重定位

静态重定位相关的必然是静态链接或者是装入时动态链接,此时地址已经完成转变

核心就是:地址是否完成转变,如果到了内存中后地址完成了转换,必然不能是运行链接

只有到了内存里面还没有完成地址转换的,才可以运行时链接,也只有动态重定位了

除上述所说两种内存管理策略以外,其他都需要动态重定位的支持

包括其可在内存中移动、可分配到不连续存储区、可不一次性装入、可推迟地址转换

可动态申请内存的这一些特点


基本分页管理所具有的特点:可分配到不连续存储区、可在内存中移动

一次性装入内存,一次性申请而不是动态申请,并且长时间驻留于内存PCB中不出来

这个是明确的,不会有内存增长问题的


基本分段的特点:可分配到不连续存储区、可在内存中移动,暂定为运行时不会变长

即“在需要的时候再链接进来,对应的也就是“运行时链接”、“动态重定位””

相对应的解释在上一节的博客内,段式优点的解释

其实这个个人目前暂时认为,段长运行阶段内是不可变的,但是段长和代码逻辑有关

因为这里谈的是“基本分段”

但依旧视作是一个不确定因素,但个人倾向于认同“动态增长”一话


请求页式、请求段式:

相对原基础上增加了“缺页处理”一项,其真正对应了“运行时链接、动态重定位”

因为不论是段式还是页式,都需要实现程序在用到了这个资源的时候再给他,缺页处理


时钟算法的代价问题:

其实更多应该是权重问题,代价而言前面几个算法的核心思想均是置换最不常访问的

也就是最不常访问的权值更高,相对应你到底改没改,就没有这个的权值那么高

也没有必要从读写角度看了,就是因为最不常访问就应该优先替换,这个的代价最低就行


内存访问相关计算问题:

对应题目:13、30、综合2、综合6、综合7

先来叙述整个访问流程的问题:

在没有快表的情况下,访问流程应该如下,此时一般页表放在内存里面,也可放寄存器


页表都放在内存里面:

第一步是得到物理地址,先访存查询内存内页表,是否存在该页

如果存在,那么利用得到的物理地址再度访问内存得到内容

如果不存在,就需要操作系统对其进行缺页处理、替换等,在这之后还需要访存一次

那么这个地址是哪里来的?到底是一次,还是两次?

需要注意的是,往往会忽略缺页处理完后依旧需要对内存进行访问的问题,即没按流程写


注:

目前不能确定,慢表的情况下是否需要再度访存得到地址,这个暂时留作一个问题


页表都放在寄存器里面:

这个是一道信息题里面的题目,其实他也没有说明具体处理策略,去除了寄存器访问时间

所以基本可以忽略不见了,同样对应上面是否需要重新访问得到地址的问题

主要就是因为快表是需要重新得到地址的,且明确说清楚的,但别的并没有明确说明


引入快表后:

一般内存里面放一个慢表,外部放一个快表的策略

首先访问快表,从里面读取页号/物理块号/物理地址,然后分情况

如果命中成功,那么只需要再根据这个物理地址访问主存读取数据即可

如果命中失败,那么需要再访问主存读慢表去获得物理地址,又需要分为两种情况

慢表里面命中成功,那么就根据慢表里面的物理地址访问主存

如果慢表命中失败,那么需要操作系统处理缺页、替换,把慢表该页表项更新,添入快表

然后,再访问快表读取物理地址,根据这个物理地址再去访问主存得到数据


其实这个画流程图会更好一些:

目前已知有快表的情况下,王道给出明确答案是需要重新访问快表的

需要注意的就是各个步骤分别的时间消耗,一定要画出完整的流程图后再进行计算

个人最容易漏的就是快、慢表均访问失败后缺页处理后,需要再度访问快表

同时比较容易漏的也就是快表访问失败后再访问主存,可能会漏掉访问快表的所需时间

总之,按照流程图一步步画下去,才能保证总体不会出问题


对应两种访问方法,一种是快表、慢表并行访问,一种是单快表访问

可以参考这个表进一步理解

这个方式也同样可以应用在Cache和主存的访问上,同时访问Cache和主存

一者访问到了,另外一者就直接取消,一者没有,另外一者也已经访问了一半了


计组内容的相应引入:

然后就可以引入Cache和计组的内容关联起来,但Cache并不需要对其进行如页表般的访问

只是单纯的,如果Cache内有,那么访问Cache即可得到数据,如果没有,那么需要访主存

就是在上述物理地址形成后,首先访问Cache,失败了再访问主存的事情罢了

页表可以理解为“间接寻址”,而Cache就是“直接寻址”

这块内容后期建议结合起来复习,都是关于存储器和存储策略的,并且本就是一回事

计组140页的图可以参考

个人暂时还没有能够把这些内容完全联系起来


磁盘、CPU、设备利用率问题:

对应题目40、41,综合5

其实这几道题的考点都是围绕“抖动”在出题,抖动的情况下,会出现大量的缺页

同时CPU利用率较低的情况,而设备利用率基本就是考虑I/O设备了

抖动的原因基本就是因为驻留集分配太少(几种内存分配法,或者说内存实在过于紧张

具体的解释:

这里的磁盘利用率,指的是“磁盘使用时间/总时间”,也就是时间上的利用率

其实这样想就能理解了,说明使用磁盘的时间比较久,大量的时间都在于磁盘的交换上面

也符合一般的直观定义即CPU利用率也是CPU使用时间/总时间

所以基本就是CPU在旁边干等着你磁盘

至于CPU利用率低,其实也有很多的可能性原因,个人思索:

大量I/O中断,即总设备利用率很高但CPU利用率不高,这时候增加计算密集型比较好

也可能是死锁了,CPU一直执行闲逛程序,外设利用率、磁盘利用率基本没有

磁盘利用率高基本考虑大量的页面交换,一般考虑是内存太小,导致缺页过度频繁


C语言程序缺页问题:

其实核心就是少了一块相应的知识介绍,这里补上对应的解释

按行优先存储,那么每次调入的时候都是基于空间局部性把相关的一行能调多少调多少

例如一页能够调一行,那么调一行,能够调两行,那么就调两行,是以页为单位调入

在内部驻留集,就是以页为单位的,可能会有多页共同存在的情况,调用也要注意一些的

对应题目:11、12、综合12


这里同时留下一个问题:

不可剥夺资源和临界资源之间的关系是?


附:

本节建议届时和计组第三章一起复习,同时完善这一章的全部结构,因为过于繁杂混乱

同时会顺便补全计组第三章内容


附:

突然想到快表的替换策略,但后来实际上一想就觉得挺好笑的

因为当内存满了,去替换一块出去,快表会删除该块、慢表会修改该块的有效位

然后快表会调入替换进来的这一块,同时慢表会修改替换进来这一块的有效位

那么不就是和内存的替换策略一样了嘛,还是对工作流程不够熟悉