3.2_3 页面置换算法

news2025/1/10 21:11:12

3.2_3 页面置换算法

  请求分页存储管理与基本分页存储管理的主要区别:

  在程序执行过程中,当所访问的信息不在内存时,由操作系统负责将所需信息从外存调入内存,然后继续执行程序。

  若内存空间不够,由操作系统负责将内存中暂时用不到的信息换出到外存

  页面置换算法的作用,就是选择:到底要把哪个页面换出到外存。

image-20240315215922135

(一)最佳置换算法(OPT)

最佳置换算法(OPT,Optimal)

  每次选择淘汰的页面将是以后永不使用,或者在最长时间内不再被访问的页面,这样可以保证最低的缺页率。

例子

  假设系统为某进程分配了三个内存块,并考虑到有以下页面号引用串(即,会依次访问这些页面):7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1

image-20240315220337197

  第一个要访问的页面是7号页面。由于刚开始内存中的内存块都是空的,所以没什么问题,将其放入内存块1即可。

  第二个要访问的页面是0号页面,同理。

  第三个要访问的页面是1号页面,同理。

  第四个要访问的是2号页面,但是,由于此时给这个进程分配的三个内存块都已经占满了,所以我们必须用页面置换算法选择淘汰其中的某一个页面、把那个页面先换出到外存。

  根据最佳置换算法的规则,我们要换出的是,在今后最长时间内不会被使用到的页面。所以,我们可以看一下,从当前访问到的这个页号开始(即第四个,2号页面)往后寻找,看一下此时在内存当中存放的7, 0, 1这三个页面出现的顺序到底是怎样的。最后一个出现的页号就是最长时间未被访问的页面,也就是要淘汰的页面

image-20240316004407428

  经过观察,我们可知,要淘汰的页面是7号页面。将其换出到外存,并将此处需要访问的2号页面放在它原来的位置上,即内存块1

  第五个要访问的是0号页面,由于它已经在内存当中了,所以此时不会发生缺页,可以正常地访问。

  第六个要访问的是3号页面,发生缺页中断,依然要看看应该淘汰哪个页面。和刚才一样,从现在这个位置往后寻找,看看此时内存当中存放的2, 0, 1三个页面出现的先后顺序。

image-20240316004652335

  我们在向后寻找的过程中,分别遇到了0、2号页面,由此便可判断出,1号页面是在今后最长时间内未被访问的。因此,选择将1号页面换出到外存。再将此处要访问的3号页面换入内存,即内存块3中。

  之后的页面访问,就不再逐个分析了,可以按照上面的方法自行判断。


  分析到最后,我们会发现,整个过程缺页中断发生了9次页面置换发生了6次

  所以,一定要注意:缺页时未必发生页面置换。若还有可用的空闲内存块,就不用进行页面置换。

  对于上例,在刚开始访问7, 0, 1这三个页面的时候,虽然它们都没有在内存当中,但是由于刚开始有空闲内存块,所以虽然会发生缺页中断、会发生调页,但是并不会发生页面置换。

  只有在内存块全部被占满之后,再次发生缺页中断的时候,才会发生页面置换。

  缺页率 = 9 / 20 = 45%。

  缺页率的计算也很简单,就是发生缺页的次数 / 总共访问多少个页面

  最佳置换算法可以保证最低的缺页率。但实际上,只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列。因此,最佳置换算法是无法实现的

(二)先进先出置换算法(FIFO)

先进先出置换算法(FIFO)

  每次选择淘汰的页面最早进入内存的页面

实现方法

  把调入内存的页面根据调入的先后顺序排成一个队列,需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块。

例子

  假设系统为某进程分配了三个内存块,并考虑到有以下页面号引用串:3, 2, 1, 0, 3, 2, 4, 3, 2, 1, 0, 4

image-20240316005958066

  第一个,访问3号页面,将其放入内存块1。此外,由于采用的是先进先出置换算法,因此还需将访问的页面按先后顺序排成队列。因此,需要将3号入队。

  第二个,访问2号页面,道理是一样的。

  第三个,访问1号页面,道理是一样的。

image-20240316010134599

  第四个,访问到0号页面的时候。由于所有内存块都已经占满了,所以必须选择一个页面进行淘汰。根据系统维持的这个队列可知,3号页面进入内存的时间是最早的。因此,选择淘汰3号页面,并将要访问的0号页面放入内存当中。相应地,3号页面出队,0号页面入队。

image-20240316010300938

  第五个,访问到3号页面的时候,同理,将此时队头的页面换出外存,将该页面换入内存。此外,队头元素出队、当前页面入队。

  剩下的过程同理,不再赘述。

  整个过程下来,发现,如果给这个进程分配三个内存块的话,总的缺页次数是9次。


  如果我们把这个题目的条件改一下,把内存块个数改为了四个

image-20240316010530253

  具体的分析过程不再说明,总之,整个过程如上表所示。

  可以发现,在页面访问序列不变的情况下,我们给内存块个数加了一个。但整个访问过程下来,缺页次数反而提升了。

  分配四个内存块时,缺页次数:10次

  分配三个内存块时,缺页次数:9次

  但是从直觉来看,内存块越多,缺页次数应该发生的越少才对。

  Belady异常——当为进程分配的物理块数增大时,缺页次数不减反增的异常现象。

  在我们要学习的这些置换算法当中,只有FIFO算法会产生Belady异常。另外,FIFO算法虽然实现简单,但是该算法与进程实际运行时的规律不适应,因为先进入的页面也有可能最经常被访问。因此,算法性能差

(三)最近最久未使用置换算法(LRU)

最近最久未使用置换算法(LRU,least recently used)

  每次淘汰的页面最近最久未使用的页面

实现方法

  赋予每个页面对应的页表项中,用访问字段记录该页面自上次被访问以来所经历的时间t

  当需要淘汰一个页面时,选择现有页面中t值最大的,即最近最久未使用的页面。

image-20240316011334199

例子

  假设系统为某进程分配了四个内存块,并考虑到有以下页面号引用串:1, 8, 1, 7, 8, 2, 7, 2, 1, 8, 3, 8, 2, 1, 3, 1, 7, 1, 3, 7

image-20240316011453437

  第一个,……,第十个,访问8号页面,都是没什么可说的,要么是直接存入,要么是不发生缺页。

  第十一个,访问3号页面时,由于四个内存块都已经满了,所以必须选择淘汰其中的某一个页面。

  在我们手动做题的时候,若需要淘汰页面,可以逆向检查此时在内存中的几个页面号。在逆向扫描过程中最后一个出现的页号就是要淘汰的页面

image-20240316011754497

  注意不要分析混了。我们在访问第十一个页面,即3号页面时,要淘汰一个页面,我们淘汰的是上表中的1, 8, 7, 2这四个在3号页面还没有存入时的、已经呆在内存里的页面。所以我们要淘汰的页面是从这四个当中选一个的。

  具体这四个中选哪一个,我们是要看:从我们此时第十一个要访问的3号页面处,往前看,逆向地扫描,看谁是最后一个出现的。也即距离当前所要访问的页面而言,最近、且最久未被访问过的页面。

  从3号页面往前看,有8、1、2号页面。因此,可以判断出,7号页面是此时最近、最久未被访问过的页面。因此,我们会选择把7号页面淘汰,然后将3号页面存入。

image-20240316013626349

  后续同理,略。

  该算法的实现需要专门的硬件支持,虽然算法性能好,但是实现困难,开销大

(四)时钟置换算法(CLOCK / NRU)

  最佳置换算法性能最好,但无法实现;

  先进先出置换算法实现简单,但算法性能差(还会有Belady异常);

  最近最久未使用置换算法性能好,是最接近OPT算法性能的,但是实现起来需要专门的硬件支持,算法开销大。

时钟置换算法

  时钟置换算法是一种性能和开销较均衡的算法,又称CLOCK算法,或最近未使用算法NRU,Not Recently Used)。

简单的CLOCK算法的实现方法

  为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列(所以,有几个内存块,循环队列的长度就是几)。当某页被访问时,其访问位置为1。当需要淘汰一个页面时,只需检查页的访问位。如果是0,就选择该页换出;如果是1,就将它置0,暂不换出,继续检查下一个页面。若第一轮扫描中所有页面都是1,则将这些页面的访问位依次置0后,再进行第二轮扫描(第二轮扫描中就一定会有访问位为0的页面了,因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描)。

image-20240316014254338

例子

  假设系统为某进程分配了五个内存块,并考虑到有以下页面号引用串:1, 3, 4, 2, 5, 6, 3, 4, 7

  前五个访问的页号,即1, 3, 4, 2, 5,都可以顺利地放入内存当中。只有考虑到第六个访问的页面时,才需要考虑淘汰哪个页面的问题。

image-20240316014707362

  内存当中的这五个页面,会通过链接指针的方式链接成一个循环队列。

image-20240316014804151

  接下来要访问6号页面,且此时五个内存块已经满了。所以要使用CLOCK算法来选择一个页面进行淘汰。

  于是,会从这个循环队列的队首开始扫描,尝试找到一个访问位为0的页面。并且,被扫描过的页面需要把访问位由1改为0

image-20240316014937257

  所以,在经过第一轮扫描之后,并没有找到访问位为0的页面,且所有的页面访问位都由1置为了0。

  那么,在进行第二轮扫描的时候,就找到了1号页面的访问位为0,从而选择淘汰此页面。

  于是,6号页会装入到1号页以前占有的这个内存块当中。并且,6号页的访问位会被置为1。并且,扫描的指针会指向下一个位置。

image-20240316015139003

  接下来,在访问过6号页之后,我们该访问3号页了。由于3号页被访问,所以3号页的访问位要由0置为1。同样地,在访问过4号页之后,它的访问位也要由0置为1。

image-20240316015353472

  需要注意的是,只是这个循环队列当中某页面的访问位由0改为1了,而与指针当前指向的位置没有关系。并不是说指针指向的是3号页,所以3号页的访问位才能得以修改;也并不是说,如果要修改4号页的访问位,则指针需要指向4号页……。

  最后一个,该访问7号页了,发生缺页。因此,要在循环队列里找到一个访问位为0的页面,并且在扫描的过程中,被扫描的页面需要把访问位由1改为0。

image-20240316015649703

  因此,3号页、4号页的访问位会由1置为0。同时,发现了访问位为0的2号页,将其淘汰,并把要访问的7号页放进去。7号页的访问位置1,同时指针指向下一个位置。

  通过上面的例子,可以看到,“扫描的指针”像一个时钟的指针转圈的过程,因此这个算法叫时钟置换算法。

  此外,我们也可以理解,为什么它还叫“最近未用算法”。每个页面都设有一个访问位,访问位为1表示最近被用过,访问位为0表示最近没有被用过。我们要选择淘汰的页面就是第一个寻找到的、访问位为0的页面。因此,这种算法也叫最近未用算法。

(五)改进型的时钟置换算法

  简单的时钟置换算法仅考虑到一个页面最近是否被访问过。

  实际上,如果被淘汰的页面没有被修改过,就不需要执行I/O操作写回外存。只有被淘汰的页面被修改过时,才需要写回外存

  我们如果优先能选择没有被修改过的页面进行淘汰的话,就不需要一直将数据写回外存,从而提高性能。

  因此,除了考虑一个页面最近有没有被访问过之外,操作系统还应考虑页面有没有被修改过。在其他条件都相同时,应优先淘汰没有修改过的页面,避免I/O操作。这就是改进型的时钟置换算法的思想。

  所以,为了达到这个目的,我们还需要为各个页面增加一个修改位

  修改位 = 0,表示页面没有被修改过;

  修改位 = 1,表示页面被修改过。

  为方便讨论,用(访问位, 修改位)的形式表示各页面状态。如(1, 1)表示一个页面近期被访问过,且被修改过。

算法规则

  和“简单的时钟置换算法”一样,我们将所有可能被置换的页面排成一个循环队列。

  1.第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。

  即,第一轮扫描中,尝试找到一个“没有被访问过、且没有被修改过”的最完美页面。

  2.第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。本轮将所有扫描过的帧访问位设为0。

  即,第二轮扫描中,尝试找到一个”没有被访问过,但是被修改过“的页面。并且,被扫描过的页面的访问位都会被置为0。

  3.第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。

  4.第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。

  分析:由于第二轮已将所有帧的访问位设为0,因此经过第三轮、第四轮扫描,一定会有一个帧被选中,因此改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描


例子

  假设系统为该进程分配了五个内存块。且此时面临的情况是,需要选择一个页面将其淘汰。循环队列的指针现指向队头。

  情况一:只需一轮扫描

image-20240316020945135

  第一轮扫描,往后寻找到第一个(0, 0)的帧,且扫描的过程中不修改任何标志位。

image-20240316021119410

  第一轮扫描时,就找到了想要的页面,从而进行淘汰。

  情况二:需要两轮扫描

image-20240316021230911

  第一轮想寻找一个(0, 0)的帧,但一圈扫描下来,并没有发现。同时,第一轮扫描是不修改任何标志位的。

  因此,会进行第二轮扫描。第二轮扫描会尝试找到一个原本就是(0, 1)的页面。并且,对于第二轮的扫描,其扫描过的页面会把访问位置为0。

image-20240316021414920

  在第二轮扫描时,对一个页面的访问位进行了修改。此外,最终找到了想要的(0, 1)

  情况三:需要三轮扫描

image-20240316021507867

  第一轮扫描下来,发现都没有(0, 0)。第一轮不修改任何标志位。

  第二轮扫描下来,发现也没有(0, 1)。第二轮扫描的同时会将被扫描到的访问位置为0。

image-20240316021620489

  进行第三轮扫描。第三轮扫描需要找到一个(0, 0)的帧。第三轮扫描不修改任何标志位。最终找到。

image-20240316021703278

  情况四:需要四轮扫描

image-20240316021720852

  第一轮扫描,未找到。

  第二轮扫描,未找到,且访问位都被置为0。

image-20240316021749213

  第三轮扫描,未找到。

  进行第四轮扫描,找到一个(0, 1)的页面。能够找到。

image-20240316021833215


再次回头思考一下这四轮背后的含义

  第一轮:从当前位置开始扫描到第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。

  第二轮:若第一轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。本轮将所有扫描过的帧访问位设为0。

  第三轮:若第二轮扫描失败,则重新扫描,查找第一个(0, 0)的帧用于替换。本轮扫描不修改任何标志位。

  第四轮:若第三轮扫描失败,则重新扫描,查找第一个(0, 1)的帧用于替换。

分析

  1.第一优先级:最近没访问,且没修改的页面。

  2.第二优先级:最近没访问,但修改过的页面。

  如果第二轮还没找到,那就说明,所有的这些页面,在此前,都一定是“被访问过”的页面,它们的访问位一定都是1。(因为我们无论是(0, 0)还是(0, 1)都尝试找过了,但没找到)

  3.第三优先级:最近访问过,但没修改的页面。

  也就是“访问位是1,修改位是0”的页面。注意,已经来到第三轮了,说明所有的页面,它的访问位原本全部是1(只不过在第二轮的扫描过程中给全部置为0了)。

  4.第四优先级:最近访问过,且修改过的页面。

  同理。

总结

image-20240316022354231

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1520320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Laravel Class ‘Facade\Ignition\IgnitionServiceProvider‘ not found 解决

Laravel Class Facade\Ignition\IgnitionServiceProvider not found 问题解决 问题 在使用laravel 更新本地依赖环境时,出现报错,如下: 解决 这时候需要更新本地的composer,然后在更新本地依赖环境。 命令如下: co…

Day43-2-企业级实时复制intofy介绍及实践

Day43-2-企业级实时复制intofy介绍及实践 1. 企业级备份方案介绍1.1 利用定时方式,实现周期备份重要数据信息。1.2 实时数据备份方案1.3 实时复制环境准备1.4 实时复制软件介绍1.5 实时复制inotify机制介绍1.6 项目部署实施1.6.1 部署环境准备1.6.2 检查Linux系统支…

Spring Cloud Gateway针对指定接口做响应超时时间限制

背景:我做的这个服务中存在要对大数据量做自定义统计的接口和大文件上传接口,接口响应用时会超过gateWay配置的全局用时,如果调整网关全局的超时时间和服务的全局超时时间是不合理的,故此想能否单独针对某个接口进行细粒度超时限制…

Spring boot java: 无效的目标发行版: 18

idea 搭建spring boot 报错java: 无效的目标发行版: 18 本人jdk 1.8 解决方案如下:

力扣L12--- 125验证回文串(java版)-2024年3月15日

1.题目 2.知识点 注1:在 Java 中,toString() 方法用于将对象转换为字符串表示形式。对于数组对象,toString() 方法将返回数组的字符串表示形式,其中包含数组中每个元素的字符串表示形式,以逗号分隔,并且包…

idea+vim+pycharm的块选择快捷键

平时开发的时候,有的时候我们想用矩形框住代码,或者想在某列上插入相同字符 例如下图所示,我想在22-24行的前面插入0000 1. Idea的快捷键:option 鼠标 2. Pycharm的快捷键:shift option 鼠标 2. Vim 块选择 v/V/c…

智能视频生产平台解决方案介绍

视频内容已经成为企业宣传、营销、培训等多维度沟通的重要媒介,美摄科技凭借其在智能视频生产领域的深厚积累和创新能力,推出了面向企业的智能视频生产平台解决方案,为企业提供多端多场景的智能化视频生产工具,助力企业轻松打造高…

单例设计模式,各种排序复习

1.单例设计模式 资料来源 1.1单例模式是什么? 单例模式,属于创建类型的一种常用的软件设计模式。 通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程…

git stash clear/drop 后如何恢复

git stash clear/drop 后代码如何恢复 事故经过 切换分支前有修改未提交的代码,使用 git stash 存储了当前的代码切换分支再返回自己开发的分支本来要进行 git stash pop 操作,然后 git stash list 发现有好几个 stash记录于是想清除没用的 stash 记录…

浅易理解:非极大抑制NMS

什么是非极大抑制NMS 非极大值抑制(Non-Maximum Suppression,简称NMS)是一种在计算机视觉和图像处理领域中广泛使用的后处理技术,特别是在目标检测任务中。它的主要目的是解决目标检测过程中出现的重复检测问题,即对于…

Sunday 算法介绍

1. Sunday 算法介绍 「Sunday 算法」 是一种在字符串中查找子串的算法,是 Daniel M.Sunday 于1990年提出的字符串模式匹配算法。 Sunday 算法思想:对于给定文本串 T 与模式串 p,先对模式串 p 进行预处理。然后在匹配的过程中,当发…

spy分析文件另存为弹框【selenium】

有时需要下载多个文件,但是不想保存在同一个目录下,需要做两步 selenium设置浏览器默认下载路径,这个路径需要是个不存在的路径操作文件另存为弹框 文章目录 selenium设置浏览器默认下载路径操作文件另存为弹框 selenium设置浏览器默认下载路…

Golang中map数据结构字段解析

Golang里map底层数据结构具体如下图所示: map其实就是一个指向 hmap 的指针,占用了8个字节 hmap各自段存放的字段意义如下: 字段含义countmap中元素的个数,对应len (map)的值flags状态标志位,标记map的一些状态B桶数…

MySQL大小写敏感、MySQL设置字段大小写敏感

文章目录 一、MySQL大小写敏感规则二、设置数据库及表名大小写敏感2.1、查询库名及表名是否大小写敏感2.2、修改库名及表名大小写敏感 三、MySQL列名大小写不敏感四、lower_case_table_name与校对规则4.1、验证校对规则影响大小写敏感4.1、验证校对规则影响排序 五、设置字段内…

FPGA静态时序分析与约束(三)、读懂vivado时序报告

系列文章目录 FPGA静态时序分析与约束(一)、理解亚稳态 FPGA静态时序分析与约束(二)、时序分析 文章目录 系列文章目录前言一、时序分析回顾二、打开vivado任意工程2.1 工程布局路由成功后,点击vivado左侧**IMPLEMENT…

SpringMVC 02

这里先附上前一篇的地址,以上系列均为博主的学习路线,仅供参考 初识Spring MVC-CSDN博客 下面我们从SpringMVC传递数组开始讲起 1.传递数组 传递数组的方式和传递普通变量的方式其实是相同的,下面我们附上传递的图片 RequestMapping("/r7")public String r1(String[…

【Git】本地仓库关联远程仓库

Git 本地项目关联远程仓库 本地 本地已有项目 ● 项目 07.GitLocalTest 包含有一个js ○ test.js 远程仓库 ● 远程仓库地址 ○ https://github.com/Sonnenlicht77/gitTest.git ○ 仓库只有一个 readme.md 关联 1.本地 1.1 本地仓库 ● git init ● git add . ● gi…

考研复习C语言进阶(3)

结构体 1 结构体的声明 1.1 结构的基础知识 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag { member-list; }variable-list; 例如描述一个学生: struct Stu { char name[20];//名字 int ag…

Java开发从入门到精通(九):Java的面向对象OOP:成员变量、成员方法、类变量、类方法、代码块、单例设计模式

Java大数据开发和安全开发 (一)Java的变量和方法1.1 成员变量1.2 成员方法1.3 static关键字1.3.1 static修饰成员变量1.3.1 static修饰成员变量的应用场景1.3.1 static修饰成员方法1.3.1 static修饰成员方法的应用场景1.3.1 static的注意事项1.3.1 static的应用知识…

03-java基础-运算符(数据类型转换)、原码、补码、反码

一、运算符 一、1、算术运算符 在代码中如果有小数参与运算,结果有可能会不精确。 一、1.1、数字相加 一、1.1.1、类型转换的分类(2种) 一、1.1.1.1、类型转换的分类1-----隐式转换 一、1.1.1.1、类型转换的分类2-----强制转换 一、1.2、字符…