页面置换算法

在进程运行过程中,若需要访问的物理块不在内存中,就需要通过一定的方式来将页面载入内存,而此时内存很可能已无空闲空间,因此就需要一定的算法来选择内存中要被置换的页面,这种算法就被称为页面置换算法。页面置换算法的好坏,将直接影响系统的性能。

一个好的页面置换算法,应做到减少页面置换的频率。尽量将以后不会用到的或较长时间不会使用的页面给置换出。

下面介绍几种常用的页面置换算法。


1. 最佳置换算法

该算法是一种理想化的算法,具有非常好的性能,但是由于目前无法预知未来,因此难以实现。

该算法选择淘汰的页面是:未来永远不会再使用的页面 or 未来最长时间不再被访问的页面。该算法保证了可以获得最低缺页率,但无法预知未来页面的使用情况,因此目前无法实现,但通常用来评价其他算法。

例:假定系统为某进程分配了三个物理块,并考虑有以下的页面号引用串:
7,0,1,2,0,3,0,4,2,3,0,3,2,1,2,0,1,7,0,1
进程运行时,先将 7,0,1 三个页面装入内存。以后,当进程要访问页面 2 时,将会产生缺页中断。此时 OS 根据最佳置换算法,将选择页面 7 予以淘汰。这是因为页面 0 将作为第 5 个被访问的页面,页面 1 是第 14 个被访问的页面,而页面 7 则要在第 18 次页面访问时才需调入。下次访问页面 0 时,因它已在内存而不必产生缺页中断。当进程访问页面 3时,又将引起页面 1 被淘汰;因为,它在现有的 1,2,0 三个页面中,将是以后最晚才被访问的。图 4-26 示出了采用最佳置换算法时的置换图。由图可看出,采用最佳置换算法发生了 6 次页面置换。


2. 先进先出(FIFO)页面置换算法

该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

例:同上。当进程第一次访问页面 2 时,将把第 7 页换出,因为它是最先被调入内存的;在第一次访问页面 3 时,又将把第 0 页换出, 因为它在现有的 2, 0, 1 三个页面中是最老的页。 由图 4-27 可以看出,利用 FIFO 算法时进行了 12 次页面置换,比最佳置换算法正好多一倍。


3. 最近最久未使用(LRU)算法

该算法以过去预测未来,选择之前最长时间未使用的页面置换。但是由于利用“过去”作为“未来”的近似这一做法并非完全可靠,因此有时会造成缺页率非常高,导致效率会非常低。

例:同上。当进程第一次对页面 2 进行访问时,由于页面 7 是最近最久未被访问的,故将它置换出去。当进程第一次对页面 3进行访问时,第 1 页成为最近最久未使用的页,将它换出。由图可以看出,前 5 个时间的图像与最佳置换算法时的相同,但这并非是必然的结果。因为,最佳置换算法是从“向后看”的观点出发的,即它是依据以后各页的使用情况;而 LRU 算法则“向前看”的,即根据各页以前的使用情况来判断,而页面过去和未来的走向之间并无必然的联系。


4. 代码实现

该部分代码使用vector来实现,未使用链表。

/*************************************************************************> 测试数据> 20> 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1> 3************************************************************************/#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;class PageReplacement {
private:vector<int> page;int page_num;  //物理内存块数
public:PageReplacement() : page_num(0) {}void create();void print();void physical_block_print( const vector<int>& );bool isfind( const vector<int>&, int );  //查找是否已在内存物理块中void FIFO();  //FIFO页面置换算法void LRU();  //LRU页面置换算法void OPT(); //OPT页面置换算法
};void PageReplacement::create() {cout << "请输入页面个数: ";int n, t;cin >> n;cout << "请输入页面串:\n";while( n-- ) {cin >> t;page.push_back( t );}cout << "请输入内存物理块数: ";cin >> page_num;
}void PageReplacement::print() {int n = page.size();cout << "页面串:\n";for( int i = 0; i < n; i++ ) {cout << page[i] << ' ';}cout << endl;
}void PageReplacement::physical_block_print( const vector<int>& t ) {int n = t.size();for( int i = 0; i < n; i++ ) {cout << t[i] << ' ';}cout << endl;
}bool PageReplacement::isfind( const vector<int> & block, int t ) {if ( find( block.begin(), block.end(), t ) != block.end() ) {return true;}return false;
}/* FIFO页面置换算法 */
void PageReplacement::FIFO() {vector<int> physical_block( page_num, -1 );int n = page.size(), cur = 0;int not_found = 0;cout << "FIFO页面置换情况:\n";for( int i = 0; i < n; i++ ) {if( !isfind( physical_block, page[i] ) ) {physical_block[cur] = page[i];  //页面置换cur = (cur+1)%page_num;not_found++;}physical_block_print( physical_block );  //输出每个物理块信息}cout << "缺页次数:"<< not_found << endl;
}/* LRU页面置换算法 */
void PageReplacement::LRU() {vector<int> physical_block( page_num, -1 );map<int, int> page_time;int n = page.size();int not_found = 0;for( int i = 0; i < n; i++ ) {if ( !isfind( physical_block, page[i] ) ) {  //当前页不在为物理块中if ( page_time.size() < page_num ) { //物理块未放满physical_block[i] = page[i];page_time[page[i]] = i;} else {  //物理块放满,进行页面置换map<int, int>::iterator it = page_time.begin(), t = it;for( it++; it != page_time.end(); it++ ) {if ( t->second > it->second ) {t = it;}}int index;for( index = 0; index < page_num && physical_block[index]!=t->first; index++ );physical_block[index] = page[i];page_time.erase( t );page_time[page[i]] = i;}not_found++;} else {  //在物理块中,更新页面最后使用时间page_time[page[i]] = i;}physical_block_print( physical_block );}cout << "缺页次数:"<< not_found << endl;
}/* OPT页面置换算法 */
void PageReplacement::OPT() {vector<int> physical_block( page_num, -1 );int n = page.size();int not_found = 0;for( int i = 0; i < n; i++ ) {if( !isfind( physical_block, page[i] ) ) {  //当前页不在物理块中if( i < page_num ) {  //物理块未放满physical_block[i] = page[i];} else {  //物理块放满,进行页面置换map<int, int> page_time;int k, j;/* 获取物理块中页面此后的最先使用时间 */for( j = 0; j < page_num; j++ ) { //遍历physical_blockfor( k = i+1; k < n; k++ ) {  //遍历pageif( physical_block[j] == page[k] ) {page_time[page[k]] = k;break;}}if( k == n ) {page_time[physical_block[j]] = k;}}/* 寻找可以置换的页面 */map<int, int>::iterator it = page_time.begin(), t = it;for( ; it != page_time.end(); it++ ) {if ( t->second < it->second ) {t = it;}}/* 获取被置换页面在物理块的下标 */int index = 0;for( ; index < page_num && physical_block[index] != t->first; index++ );physical_block[index] = page[i];}not_found++;}physical_block_print( physical_block );}cout << "缺页次数:"<< not_found << endl;
}int main() {PageReplacement t;t.create();// t.FIFO();t.LRU();// t.OPT();return 0;
}

【操作系统】页面置换算法相关推荐

  1. 操作系统——页面置换算法练习题

    操作系统--页面置换算法练习题 1.设某计算机的逻辑地址空间和物理地址空间均为64KB,按字节编址.若某进程最多需要6页(Page)数据存储空间,页的大小为1KB,操作系统采用固定分配局部置换策略为此 ...

  2. 2020-11-22(操作系统——页面置换算法)

    当内存中的页面满了之后,需要的数据又在磁盘虚拟内存中,可以使用页面置换算法将需要的页置换到物理内存中.下面先介绍几种局部页面置换算法,其针对一个进程而言的页面置换. 一.局部页面置换算法 1.最优页面 ...

  3. 计算机操作系统——页面置换算法

    声明:本篇博客参考书籍<计算机操作系统>(西安电子科技大学出版社) 文章目录 一.最佳页面置换算法 1.基本知识 2.算法思想 二.先进先出(FIFO)页面置换算法 1.基本知识 2.算法 ...

  4. 操作系统——页面置换算法

    一.页面置换算法简介 操作系统将内存按照页的进行管理,在需要的时候才把进程相应的部分调入内存.当产生缺页中断时,需要选择一个页面写入.如果要换出的页面在内存中被修改过,变成了"脏" ...

  5. 操作系统页面置换算法(opt,lru,fifo,clock)实现

    选择调出页面的算法就称为页面置换算法.好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出. 常见的置换算法有以下四种(以下来自操作系统课本). ...

  6. 操作系统-页面置换算法

    实验六:页面置换算法 一. 实验目的( 页面置换 ) 在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断.当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选 ...

  7. 操作系统页面置换算法之先进先出(FIFO)页面置换算法(C语言实现)

    先进先出(FIFO)页面置换算法 [注]本代码数据及思路方法参考自<计算机操作系统(第四版)>汤小丹等 编著的教材. #include <iostream>int access ...

  8. 操作系统页面置换算法实验报告

    实验指导 一 .页面置换算法的基本内容 1.1 页面置换算法是在当进程运行过程中,若其要访问的页面不在内存且内存已满时,要决定将哪个页面换出的算法.常见的页面置换算法包括最佳置换.先进先出置换.最近最 ...

  9. 操作系统页面置换算法

    通常把选择换出页面的算法称为页面置换算法,置换算法的好坏直接影响到系统的性能,不适当的算法可能会导致抖动, 最近学习了一下,算是做一个笔记吧... 实现OPT和LRU置换算法 #include < ...

  10. 操作系统页面置换算法(最佳置换算法,FIFO,LRU,Clock)

    页面置换算法 为什么要页面置换 最佳置换算法 先进先出页面置换算法 LRU置换算法 Clock置换算法 为什么要页面置换 缺页中断: 在地址映射过程中,若在页表中发现所要访问的页面不在内存,则产生中断 ...

最新文章

  1. solrlucene3.6.0源码解析(三)
  2. Oracle表空间规划处理
  3. 百度牵头,全球首个面向商业化运营的Robotaxi技术标准正式发布
  4. 教你如何一篇博客读懂设计模式之—--工厂模式
  5. 【Python】内置os.path模块最常用的一些用法
  6. WSL1安装GUI界面
  7. 利用wordpress搭建自己的网站(百度云虚拟主机)
  8. Java 并发编程的艺术
  9. 阿铭Linux_公有云学习笔记20190116
  10. Mac 生成ico图标
  11. css3实现动画的三种方式
  12. SpringBoot的属性注入详解
  13. Android读书笔记
  14. InfluxDB添加用户认证
  15. Echarts实现中国地图线路图特效(一对多发射点)
  16. 模拟器也可以使用摄像头,不用真机也可以测试摄像头程序 ,
  17. linux 查找替换
  18. cad角度命令怎么输入_CAD教程 | CAD大佬也是这样过来的,制图命令的输入方法及操步骤...
  19. UVALive 7279 Sheldon Numbers (暴力打表)
  20. JS和CSS的引入/写入位置应该放在哪里?

热门文章

  1. CSS多列布局(实例)
  2. R语言中级--自定义方程
  3. spring boot高性能实现二维码扫码登录(上)——单服务器版
  4. 20170117小测
  5. HTTPS协议在Tomcat中启用的配置
  6. nginx环境下搭建nagios 3.5.0,及配置pnp4nagios画图
  7. 2014-08-26 遇到的小问题
  8. 《那些年啊,那些事——一个程序员的奋斗史》——78
  9. (转)利用MS AJAX 扩展服务器端控件
  10. 计算机斐波那流程图,循环结构——斐波那契数列.DOC