哈工大操作系统学习笔记十二——内存换入换出

哈工大os学习笔记十二(内存换入换出)

基于现在为止,内存管理进程管理CPU管理,再加上后面的外围的设备驱动,文件管理,操作系统启动和一些接口,系统初始化,系统引导,把这些合在一起,能形成一个完成的样子轮廓,把内容掰碎理解消化了,对系统有一个完整的认识,也就有可能做出一个操作系统,至少能在一个操作系统中做一些更改,模块性的设计和实现。到此内存管理部分学习暂时结束。

换入换出实现虚拟内存


一、 内存的换入——请求调页

1.换入的解释

在这里插入图片描述
在这里插入图片描述
用户可随意使用该“内存”,就像单独拥有4G“内存”,这个“内存”怎么映射到物理内存,对用户透明的。提供4G内存的假象。
在这里插入图片描述
物理内存可能没有4G这么大,可能为1G 2G,但是给用户的感觉是4G。
怎么用1G的物理内存给用户提供4G的感觉?
使用换入换出解决。
现实世界中的仓库与门店,仓库是大的,门店大小是有限的。
请求的时候才进行映射。

2.实现换入——请求调页

把页面调入物理内存中,就是将对应虚拟内存映射到物理内存里。
在这里插入图片描述
在这里插入图片描述
页都存储在磁盘中。MMU查页表发现缺页,这里用中断进行处理。load[addr]执行完毕后进入中断程序,中断返回时一般都执行下一条指令,这时通过硬件让PC指针不动。
在这里插入图片描述
在这里插入图片描述
中断处理将缺的页从磁盘换入到物理内存。

基本流程是:一个逻辑地址CS:IP,首先根据CS在段表中找到对应的基址,加上偏移得到 虚拟地址:页号+偏移。然后根据页号在页表中找到对应的页框号,加上偏移得到物理地址。但是如果在页表中找不到对应的页号对应的页框地址的话,就要从磁盘上将这一页换入了。这个换入采用的是中断的形式,如果load[addr]的时,发现addr在页表里面没有对应映射,那么就将中断向量寄存器的某一位置为一,说明有中断产生。然后在中断服务函数里面将addr导入到物理内存中。然后再次执行load[addr]这条语句。MMU 进行查表 。

3.请求调页代码实现

查找硬件手册看对应的中断号,初始化的时候设置好中断处理程序。
在这里插入图片描述
和系统调用,系统初始化,设备驱动文件磁盘管理柔和在一起os就呼之欲出。

在这里插入图片描述

现在中断进入了内核,所以有一大通汇编代码进行精细的操作,这就要保护现场一些东西(进内核栈)。线性地址=虚拟地址。汇编语言压栈绝大多数都是要进行c函数的调用。尤其是后面看到call的时候。要调用c函数就要进行传参。
在这里插入图片描述
虚拟地址address传入后就可以做do_no_page,由于你没有页,要做的就是把,磁盘上的页读入,并且建立映射,当然还要在内存中申请空闲页。
在这里插入图片描述
get_free_page//获取空闲页
bread_page//读磁盘,第一个参数是要读到的位置(内存页),第二个参数是要读取的设备(后面会讲)
put_page//建立映射,也就是填写页表。
这时候中断返回,就可以执行缺的页了。
在这里插入图片描述

在这里插入图片描述
put_page修改页表,细节实现也很精细。

二、 内存的换出

有换入就要有换出,一直往里换,迟早会满

1.内存换出

首先还是get_free_page (),在获得空闲页的时候不能总是获取新的页,内存是有限的。
所以要选择一个页换出去,淘汰,但是到底要选择哪个页?这是个问题,所以内存的换出主要讲一些算法。
内存换出的时间点,是do_no_page,查找页的时候没有映射,缺的页就要从磁盘换入,利用中断。换入检查内存够不够,不够大就要把垃圾的淘汰换出,让位。
相应的算法就填在获取空闲页的位置(get_free_page)。
在这里插入图片描述

2.内存换出算法

2.1 FIFO算法

  • FIFO算法

调度——选择资源进行分配
淘汰——选择对象剥夺资源
一个算法的优劣,对产生的结果而言,有哪些影响因子能成为评价准则的一部分。也就是算法优化的目标(这里是缺页的次数)。
下面这一个列可以想象成窗口。
在这里插入图片描述
发生缺页,D若是把A换出去,紧接着A又要使用,有发生缺页,换页太频繁,换入换出就要去磁盘上读写,读写是慢的。这就先来先服务的缺点。所以希望读写换入换出的次数少。
但是换掉哪一页合适呢?我们应该根据后面的序列来进行判断到底换出哪一页未来一段时间内C不会用到所以换C最合适,换其他的会导致换页太频繁。

2.2 MIN算法

  • MIN算法
    在这里插入图片描述
    缺页次数5次,存在的问题是,要往后看,也就是未来要执行的是什么,但是未来是无法预测的。
    所以引出LRU算法,用过去的历史预测未来。

2.3 LRU算法

  • LRU算法least recent use
    LRU具体怎么预测的未来——利用了著名的局部性。程序会在某一个地方经常使用,如果没有局部性而是完全随机的,那么换出谁都不合适。例如:最近一段时间某个商品卖的非常好,老板就会多进一些这个商品。知晓未来是不可能的,所以只能预测。在这里插入图片描述

最近最少使用的是C,将C换出,后面又用到了A——这就利用了局部性的特点。做系统的时候要抓住我们做的这个对象的客观规律,抓住了才可以做出漂亮的系统。LRU效果不错。

  • 客观世界:局部性,稀疏性,低秩性

  • LRU置换算法实现

  • 很巧妙的利用时间戳,缺页利用时间戳最小的值换出

  • 实际操作系统实现很困难,每执行一条指令,进行地址重定位,需要查看当前页面的时间戳,效率很低,然后还要考虑时间戳溢出
    在这里插入图片描述

  • 选择最小的时间戳换出,越小表示离得越远,大表示最近使用过。

  • LRU准确实现,用页码栈

  • 栈顶始终是最近访问的页面
    在这里插入图片描述
    实际系统中有问题,甚至是不可行的。每访问一次地址,进行地址翻译,查页表,所以就要维护修改时间戳,找到要修改的时间戳的位置上也花费代价,并且每执行指令要修改时间戳,改来改去时间戳非常可能溢出。每执行一条指令要做这么多的事情,开销太大计算机会变慢好多。综上维护代价太大,模拟还可以用下,现实不可行。
    具体使用栈来做,不能用数组,数组的话拷贝代价太大,但是即使是栈,也要修改10多次指针,代价还是很大。所以要考虑他的近似实现。

2.4 二次机会算法

  • 二次机会算法

  • LRU近似实现
    实际代价太多,LRU近似实现——将时间计数变为是和否。计算机要考虑极值。在这里插入图片描述

  • 循环一圈,不是之前的最近最少访问,近似成:最近没有访问,转一圈如果没有改变值,即是该值最近没有被访问过。

  • 具体操作是这样的,每页增加一个引用位( R ),每一次访问该页时,就将该位置为1。当发生缺页时用一个指针查看每一页的引用位。如果是1则将其置为0——1表示该页访问过,访问过置成0,不淘汰他;如果是0就直接淘汰——0表示没访问过,就淘汰他。

  • 这里面的1表示访问过,不是最近最少,而是只要访问过,就给你一次机会。这样转过一圈之后1是被置为0,置为0表示没被使用过

  • 代价少的原因:每访问一页只要设置R就可以了——只要修改一个数,就可以了,并且R可以放在页表项中,由MMU自动做,置换的时候怎么转圈是容易的,而上面的方式要维护的数据结构太麻烦——修改时间戳,在栈中的位置。

  • Clock算法:SCR这一实现方法称为Clock Algorithm
    在这里插入图片描述

用这种方式实现就不必维护时间戳了,提高了内存使用效率。但是这种算法真的可以使用吗?在实际中,缺页的情况肯定不会很多——程序具有局部性;如果程老缺页,说明内存太小了或者算法不行。那当这个算法缺页很少的情况会怎么样呢?就说明总被访问,R就会全是1。

假设初始状态所有的页的引用位都是1,这是很有可能的,因为缺页情况少,进程使用的一直是内存里面存在的页。那么当发生缺页时,指针转一圈之后将所有的页的引用位都置为0,没找到能替换的,继续转,这时候发现最开始那个页引用位为0,将其置换出去,指针后移;然后又一段很长时间没有发生缺页,所有页的引用位都为1,当发生缺页之后,又会将这一轮最开始的那一页置换出去;然后指针后移,一段时间之后发生缺页,又会将这一轮最开始的那一页置换出去。这不是变成FIFO了吗。

2.5 Clock算法改进

在这里插入图片描述

  • 究其原因还是因为指针扫描的时间太长了,也就是记录了太长的历史信息——没办法表达最近这个概念,老长老长时间了,那么一大堆页都被记录了,也就无法表达最近的意思。
  • 其中一个解决办法是再加一个扫描指针用来定时清除每一页的引用位(R位),这个时间也可以控制,可以把时间缩短并且清除R位清除的快。最近一段时间都被清除为0后(快慢指针),而清除成0的这一段时间又没有被使用,再一看是0就把他换出——从上一次清除变成0的时候到现在要替换的时候没被使用,就表达出了最近没使用的含义。
    可以放在时钟中断里面,定时清除;这个时间可以事先设置好,也可以在软件里面实现,可以控制值时间长短。
    在这里插入图片描述

3.分配页框

嗯嗯,现在置换策略有了,但是还有一个问题需要解决:给进程分配多少个页框。
在这里插入图片描述

如果分配的多了,那么请求调页导致的内存高效利用就没有了。而且内存就那么大,如果每一个进程分配很多的话,跑的进程数量就少了。如果分配的少,系统内进程增多,每个进程的缺页率增大,当缺页率大到一定程度,进程就会总等待调页完成,导致cpu利用率降低。
如图,中间那个急剧下降的状态称为颠簸(不断的在磁盘和内存进行换入换出调页)。一种可以采用的方法是,先给进程分配一定数量的页框,如果增加页框能增加cpu利用率,就慢慢增加,如果导致cpu利用率减少,就降低页框分配。当然实际情况下每个进程对应的页框数量肯定是得动态调整的。按道理说应该覆盖住局部,但是局部不好求,也有一些算法来求他,比如用算法求工作集,然后在分配页框。
在这里插入图片描述
当进程太多的时候怎么分配页框都不够了,这时候就要限制进程的数量。

三、内存总结

  • 理解:页面换入换出==>实现虚拟内存==>为了实现段页机制==>为了实现程序执行起来==>最终为进程

  • 一个进程分为很多段,形成很多页面,但是页框可能不足够,此时产生缺页中断,进行页面调入调出

  • 当访问内存时,页面不存在,产生缺少中断,然后从磁盘中调入到页面到物理内存,此时可能页框满,需要根据clock算法将页面写入到磁盘,然后再将调入的页面写入到内存中

  • swap分区管理
    在这里插入图片描述

核心:基于分段分页的虚拟内存,内存换入换出实现虚拟内存技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值