实验三 内存管理
一、实验目的
1、了解虚拟存储技术的特点,掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
2、了解程序设计技术和内存泄露的原因
二、实验内容
1、模拟实现请求页式存储管理的几种基本页面置换算法
(1)最佳淘汰算法(OPT)
(2)先进先出的算法(FIFO)
(3)最近最久未使用算法(LRU))
三、实验原理
1、虚拟存储系统
UNIX中,为了提高内存利用率,提供了内外存进程对换机制;内存空间的分配和回收均以页为单位进行;一个进程只需将其一部分(段或页)调入内存便可运行;还支持请求调页的存储管理方式。
当进程在运行中需要访问某部分程序和数据时,发现其所在页面不在内存,就立即提出请求(向CPU发出缺中断),由系统将其所需页面调入内存。这种页面调入方式叫请求调页。
为实现请求调页,核心配置了四种数据结构:页表、页框号、访问位、修改位、有效位、保护位等。
2、页面置换算法
当CPU接收到缺页中断信号,中断处理程序先保存现场,分析中断原因,转入缺页中断处理程序。该程序通过查找页表,得到该页所在外存的物理块号。如果此时内存未满,能容纳新页,则启动磁盘I/O将所缺之页调入内存,然后修改页表。如果内存已满,则须按某种置换算法从内存中选出一页准备换出,是否重新写盘由页表的修改位决定,然后将缺页调入,修改页表。利用修改后的页表,去形成所要访问数据的物理地址,再去访问内存数据。整个页面的调入过程对用户是透明的。
(1)最佳淘汰算法(OPT):选择永不使用或在未来最长时间内不再被访问的页面予以替换。
(2)先进先出的算法(FIFO):选择在内存中驻留时间最久的页面予以替换。
(3)最近最久未使用算法(LRU):选择过去最长时间未被访问的页面予以替换。
3、首先用srand( )和rand( )函数定义和产生指令序列,然后将指令序列变换成相应的页地址流,并针对不同的算法计算出相应的命中率。
(1)通过随机数产生一个指令序列,共320条指令。指令的地址按下述原则生成:
A:50%的指令是顺序执行的
B:25%的指令是均匀分布在前地址部分
C:25%的指令是均匀分布在后地址部分
具体的实施方法是:
A:在[0,319]的指令地址之间随机选取一起点m
B:顺序执行一条指令,即执行地址为m+1的指令
C:在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’
D:顺序执行一条指令,其地址为m’+1
E:在后地址[m’+2,319]中随机选取一条指令并执行
F:重复步骤A-E,直到320次指令
(2)将指令序列变换为页地址流
设:页面大小为1K;
用户内存容量4页到32页;
用户虚存容量为32K。
在用户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第 0 条-第 9 条指令为第0页(对应虚存地址为[0,9])
第10条-第19条指令为第1页(对应虚存地址为[10,19])
………………………………
第310条-第319条指令为第31页(对应虚存地址为[310,319])
按以上方式,用户指令可组成32页。
四、实验中用到的系统调用函数(包括实验原理中介绍的和自己采用的),自己采用的系统调用函数要按照指导书中的格式说明进行介绍。
模拟程序无用到系统调用函数
五、实验步骤
数据结构:
(1)类PageObject:页面对象,包含页号NO和已在内存中停留的时间stayTime。
(2)address[TotalInstruction]:这是一个长度为320的int类型指令地址数组,用来存储按实验要求构造的指令序列。TotalInstruction已事先宏定义为320。
(3)InstrucPage:这是一个PageObject类型的长度为TotalInstruction的动态数组,每一号对应一条指令的所在页面,用于将指令序列转化为页地址流。
(4)Truepage:这是一个PageObject类型的动态数组,上述InstrucPage数组在构造完成后由于实验要求的规则(顺序执行一条指令,其地址为m’+1)会出现连续两个的相同页面,Truepage数组为将上述数组的连续页面处理过后的真正的页地址流。
(5)phyMemory:这是一个PageObject类型的动态数组,代表系统当前的内存块。
实验思路:
以上述的页面按要求构造指令序列,再将其转化为页地址流,构造出真正的页地址流数组。初始化物理内存块,按页地址流依次读取系统运行需要用到的页面,判断当前请求页面是否存在内存块中,如存在,则直接使用,如不存在,判断是否有空闲内存块,如有,则占用该内存块直接调入页面,如无,则使用页面置换算法将合适页面置换出去,换入需要页面。结束后处于物理内存块内的页面滞留时间全部加1。
附:在读取页地址流里首先应该判断需要的页面号是否小于最大页号,即申请越界检测,但由于模拟程序中页地址流是系统在限定范围内随机产生构造而成,所以不会发生越界错误,故在程序及流程图中没有体现越界检测这一环节,但实际操作中越界检测是必不可少的。
FiFO:选择内存中驻留时间最久的页面进行置换。在FIFO算法实现中只需要找到此刻内存块页面中驻留时间stayTime最长的页面将其置换出去即可。
LRU:选择过去最长时间未被访问的页面进行置换。在LRU中,如果需要用到的页面已在内存中,则将该页面驻留时间stayTime清0,其他与FIFO一致。
OPT:选择永不使用或在未来最长时间内不再被访问的页面进行置换。在这个算法实现中,需要用到一个int类型的Distance数组,长度为内存块数。当需要置换页面时,对每一个已在内存的页面,在页地址流中进行寻找,记下页地址流中距离下次访问该页面的距离。计算结束后对比Distance中每个页面的数值,找出最大数值的下标号,这代表该页为永不使用或在未来最长时间内不再被访问的页面。将其对应内存块的页面滞留时间stayTime置为无穷大。其他与FIFO一致。
流程图:
六、实验结果分析(截屏的实验结果,与实验结果对应的实验分析)
按算法理论来说,FIFO的缺页率应该是最高的,OPT的缺页率是最低的。
设置物理内存块数量为10,此时的各算法缺页率:
FIFO:
LRU:
OPT:
通过重复实验,可以得出,当物理内存块数为10时,FIFO缺页率在65-75%之间,LRU缺页率在60-70%之间,OPT算法缺页率最少,在37-45%之间。
改变内存块数为5执行实验:
FIFO:
LRU:
OPT:
通过重复实验,可以得出,当物理内存块数为5时,FIFO缺页率为80-87%之间,LRU缺页率为78-84%之间,OPT缺页率为55-60%之间。
改变物理内存块数,页面置换算法的缺页率也随之改变。内存块数越大,证明系统内存可存放页面越多,缺页的可能性就越小,减少内存块数,缺页的可能性就越大,所以缺页率也就越高。
在FIFO与LRU算法的随机试验中,LRU缺页率会较FIFO低一些,但如果单单对比FIFO与LRU执行一次的话,LRU不一定会比FIFO低,因为缺页的概率总是随机的,数据的不确定性直接导致了缺页的不确定性。但如果多次执行这两个算法,LRU的表现优秀于FIFO。
在算法效率方面,LRU与FIFO的时间复杂度一致,OPT的时间复杂度最高,且执行时间也最长。在计算内存内页面下次需要使用的距离时,对每一个内存块内的页面,在最坏的情况下可能要将余下页地址流全部遍历完毕,最最坏的情况下,这样的时间要乘以内存块数。这大大增加了程序的执行时间,在尽量保留OPT算法的功能性的前提下,对算法进行改造,可以设定一个上限距离,规定距离超过100则表示该页面在未来最长时间内不会被访问或者永不使用。
七、思考题
1、从几种算法的命中率看,哪个算法最高?哪个算法最低?对每个页面的执行结果进行分析。
答:从几种算法的命中率看,OPT算法的命中率最高,FIFO算法的命中率最低。
FIFO算法:
按入内存顺序依次换出页面5 2 4 1 10,可以明显在截图最后看到,请求页号5换出页号10,此时,若为OPT算法,在第一次请求换出的时候就不应该选择5换出,因为不久的将来即将用到页面5,此时OPT就避免了此次缺页,这样类似的情况一多,OPT的命中率自然就比FIFO高出很多。
2、OPT算法在执行过程中可能会发生错误,为什么?
答:OPT算法选择为永不使用或未来最不可能使用的页面,这种算法只存在于理想状态,在现实中很难实现,OPT算法假设未来可能要用到的页面与过去已使用过的页面情况一致,从而对未来要使用到的页面进行预测,虽然说有局部性,但在实际使用当中还是不一定的。
八、实验数据及源代码(学生必须提交自己设计的程序源代码,并有注释,源代码电子版也一并提交),包括思考题的程序。
程序完整代码请转至个人GitHub仓库(如果喜欢,麻烦点个star✨谢谢~)
结语:随笔仅供参考,千万不要照抄哦,我相信你可以的~!