(待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录
00 简介
01 算法概述
02 公用方法与变量解释
03 先进先出置换算法(FIFO)
04 最近最久未使用(LRU)算法
05 最佳置换算法(OPT)
00 简介
页面置换算法主要是记录内存的忙闲状态,为进程分配和释放内存。当主存的空间太小而无法装入所有的进程时,就需要在内存和硬盘之间进行调度操作。
多数操作系统只采用某种特定的页面置换算法进行置换,无法预先探测当前运行进程的页面访问模式,因此不能根据不同的页面访问模式,选用不同的页面置换算法。当然,如果能对不同的访问模式选取相应的页面置换算法,将提高操作系统的调度能力,进而提高整个系统的性能。
此处采用C#语言中的动态数组(ArrayList)进行对三种算法的模拟。
01 算法概述
1 先进先出置换算法(FIFO)
最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。建立一个FIFO队列,收容所有在内存中的页。被置换页面总是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。
这种算法只是在按线性顺序访问地址空间时才是理想的,否则效率不高。因为那些常被访问的页,往往在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。
FIFO的另一个缺点是,它有一种异常现象,即在增加存储块的情况下,反而使缺页中断率增加了。当然,导致这种异常现象的页面走向实际上是很少见的。
2 最佳置换算法(OPT)
最优置换(Optimal Replacement)是在理论上提出的一种算法。其实质是:当调入新的一页而必须预先置换某个老页时,所选择的老页应是将来不再被使用,或者是在最远的将来才被访问。采用这种页面置换算法,保证有最少的缺页率。
但是最优页面置换算法的实现是困难的,因为它需要人们预先就知道一个进程整个运行过程中页面走向的全部情况。不过,这个算法可用来衡量(如通过模拟实验分析或理论分析)其他算法的优劣。
3 最近最久未使用(LRU)算法
FIFO算法和OPT算法之间的主要差别是,FIFO算法利用页面进入内存后的时间长短作为置换依据,而OPT算法的依据是将来使用页面的时间。如果以最近的过去作为不久将来的近似,那么就可以把过去最长一段时间里不曾被使用的页面置换掉。它的实质是,当需要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。这种算法就称为最久未使用算法(Least Recently Used,LRU)。
LRU算法是与每个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。
LRU算法是经常采用的页面置换算法,并被认为是相当好的,但是存在如何实现它的问题。LRU算法需要实际硬件的支持。其问题是怎么确定最后使用时间的顺序,对此有两种可行的办法:
(1)计数器。
最简单的情况是使每个页表项对应一个使用时间字段,并给CPU增加一个逻辑时钟或计数器。每次存储访问,该时钟都加1。每当访问一个页面时,时钟寄存器的内容就被复制到相应页表项的使用时间字段中。这样我们就可以始终保留着每个页面最后访问的“时间”。在置换页面时,选择该时间值最小的页面。这样做,不仅要查页表,而且当页表改变时(因CPU调度)要维护这个页表中的时间,还要考虑到时钟值溢出的问题。
(2)栈。
用一个栈保留页号。每当访问一个页面时,就把它从栈中取出放在栈顶上。这样一来,栈顶总是放有目前使用最多的页,而栈底放着目前最少使用的页。由于要从栈的中间移走一项,所以要用具有头尾指针的双向链连起来。在最坏的情况下,移走一页并把它放在栈顶上需要改动6个指针。每次修改都要有开销,但需要置换哪个页面却可直接得到,用不着查找,因为尾指针指向栈底,其中有被置换页。(此次模拟运用该方法)
因实现LRU算法必须有大量硬件支持,还需要一定的软件开销。所以实际实现的都是一种简单有效的LRU近似算法。
一种LRU近似算法是最近未使用算法(Not Recently Used,NUR)。它在存储分块表的每一表项中增加一个引用位,操作系统定期地将它们置为0。当某一页被访问时,由硬件将该位置1。过一段时间后,通过检查这些位可以确定哪些页使用过,哪些页自上次置0后还未使用过。就可把该位是0的页淘汰出去,因为在最近一段时间里它未被访问过。
02 公用方法与变量解释
C#中的动态数组不在默认项目中给的命名空间里,若调用,需要引入下面所示的命名空间:
using System.Collections;
这是对下面的部分变量的解释。
OriginalArray
//原始数组,静态数组,存放整个页面串
ManagedArray
//被管理数组,动态数组,模拟物理块/栈结构
index
//序列号,标记即将进入到物理块的元素所对应的序号
OriginalIndex
//同上
在三种算法的实现过程中,都涉及到把页面串中的元素放入物理块中,当物理块中存在与将放入物理块中的页面串内元素相同的元素时,FIFO算法和Optimal算法不对元素进行处理,LRU算法中(运用了栈的方法)把相同元素放在栈顶。否则做另外操作。对页面串和物理块中是否遇到相同元素判断用此方法。
01 方法:判断接下来要放入物理块中元素与物理块中现存元素是否相同。
02 方法需求:物理块/栈模拟数组,原页面串模拟数组,判断序号index。
03 执行过程:遍历物理块,如果物理块中元素与将要放入物理块元素相同,则返回true,遍历结束后证明不存在,返回false。
04 返回值:存在为true,不存在为false。
bool checksame(int[] OriginalArray, ArrayList ManagedArray, int OriginalArrayIndex)
{
for (int i = ; i < ManagedArray.Count; i++)
{
if (Convert.ToInt32(ManagedArray[i]) == OriginalArray[OriginalArrayIndex])
{
return true;
}
}
return false;
}
03 先进先出置换算法(FIFO)
private void FIFO(int[] OriginalArray)
{
int PageLength = OriginalArray.Length;
int cursor = ;
for (int i = ; i < OriginalArray.Length; i++)
{
if (ManagedArray.Count < blockCount)
{
if (checksame(OriginalArray, ManagedArray, i) == false)
{
ManagedArray.Add(OriginalArray[i]);
} }
else
{
if (checksame(OriginalArray, ManagedArray, i) == false)
{
ManagedArray[cursor] = OriginalArray[i];
cursor++;
if (cursor >= blockCount)
{
cursor = ; }
}
} //[show the result code] }
}
04 最近最久未使用(LRU)算法
private void LRU(int[] OriginalArray)
{
int PageLength = OriginalArray.Length;
for (int i = ; i < OriginalArray.Length; i++)
{
if (ManagedArray.Count < blockCount)
{
if (checksame(OriginalArray, ManagedArray, i) == true)
{
ManagedArray.Remove(OriginalArray[i]);
}
else { };
ManagedArray.Add(OriginalArray[i]);
}
else
{
if (checksame(OriginalArray, ManagedArray, i) == false)
{
ManagedArray.RemoveAt();
}
else
{
ManagedArray.Remove(OriginalArray[i]);
}
ManagedArray.Add(OriginalArray[i]);
} //[show the result code] }
}
05 最佳置换算法(OPT)
1 private int getdistance(ArrayList ManagedArray, int[] OriginalArray, int OriginalIndex, int ManagedIndex)
{
int distance = ; if (OriginalIndex < OriginalArray.Length)
{
for (int i = OriginalIndex; i < OriginalArray.Length; i++)
{
if (OriginalArray[i] == Convert.ToInt32(ManagedArray[ManagedIndex]))
{
distance = i - OriginalIndex;
break;
}
else
{
distance = OriginalIndex + OriginalArray.Length + ;
// make Original[i]'s distance max
}
} }
return distance;
}
1 private void OPT(int[] OriginalArray)
2 {
3 PageLength = OriginalArray.Length;
4
5 int[] distances = new int[blockCount];
6 for (int i = 0; i < distance.Length; i++)
7 {
8 distance[i] = 0;
9 }
10
11
12 for (int i = 0; i < OriginalArray.Length; i++)
13 {
14 if (ManagedArray.Count < blockCount)
15 {
16 if (checksame(OriginalArray, ManagedArray, i) == false)
17 {
18 ManagedArray.Add(OriginalArray[i]);
19 }
20
21 }
22 else
23 {
24 if (checksame(OriginalArray, ManagedArray, i) == false)
25 {
26
27 for (int k = 0; k < ManagedArray.Count; k++)
28 {
29 distances[k] = getdistance(ManagedArray, OriginalArray, i, k);
30 }
31
32
33 for (int m = 0; m < distances.Length; m++)
34 {
35 if (distances[m] == distances.Max())
36 {
37 ManagedArray[m] = OriginalArray[i];
38 break;
39
40 }
41 }
42 }
43
44
45 }
46
47 //[show the result code]
48 }
(待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)的更多相关文章
- 关于C#中的动态数组ArrayList
在C#中,如果需要数组的长度和元素的个数随着程序的运行不断改变,就可以使用ArrayList类,该类是一个可以动态增减成员的数组. 一.ArrayList类与Array类的区别 ArrayList类实 ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- C#动态数组ArrayList和List<T>的比较
C#中一维动态数组(即列表)分ArrayList和List<T>两种,其容量可随着我们的需要自动进行扩充 一.ArrayList类(少用) ArrayList位于System.Collec ...
- [数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习)
[数据结构1.2-线性表] 动态数组ArrayList(.NET源码学习) 在C#中,存在常见的九种集合类型:动态数组ArrayList.列表List.排序列表SortedList.哈希表HashTa ...
- C语言基础 - 实现动态数组并增加内存管理
用C语言实现一个动态数组,并对外暴露出对数组的增.删.改.查函数 (可以存储任意类型的元素并实现内存管理) 这里我的编译器就是xcode 分析: 模拟存放 一个 People类 有2个属性 字符串类型 ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- C语言中的指针数组
C语言中的指针数组是什么,像 char *a[]={"ddd","dsidd","lll"}; 这里讲一下注意如果我们使用了a也就是首元素的 ...
- C语言中指针和数组
C语言数组与指针的那些事儿 在C语言中,要说到哪一部分最难搞,首当其冲就是指针,指针永远是个让人又爱又恨的东西,用好了可以事半功倍,用不好,就会有改不完的bug和通不完的宵.但是程序员一般都有一种迷之 ...
- 页面置换算法——最近最久未使用算法(c语言实现)
操作系统实验:用C语言编程实现最近最久未使用置换算法(LRU) 最近最久未使用置换算法(LRU),全称Least Recently Used,是一种页面置换算法. 对于在内存中但又不用的数据块(内存块 ...
随机推荐
- [CSS]多浏览器兼容的垂直居中,兼容多个IE
相信你都是在兼容垂直居中而烦恼,翻阅多个网站总是找不到理想的方法而苦恼,来到这里你的问题解决了!如果对你有帮助请点个赞,谢谢. 多兼容垂直居中,在IE6-9亲自测试并通过 <!doctype h ...
- 通过浏览器https能够访问SVN,但eclipse SVN,tortoiseSVN始终连接不上SVN的问题解决方案
为了便于本地代码维护,特意在本地搭建了一个visualSVN服务器用于本地代码管理,但是最近突然出现问题,eclipse上的SVN资源库始终连接不上,提示 "svn: connection ...
- golang中string以及slice之间的一些问题
好记性不如烂笔头o_O slice切片不会开辟新的空间 a := []int{0,1,2,3} b := make([]int, 8) b = a[:] b[2] = 9 fmt.Println(a) ...
- PHP抓取及分析网页的方法详解
本文实例讲述了PHP抓取及分析网页的方法.分享给大家供大家参考,具体如下: 抓取和分析一个文件是非常简单的事.这个教程将通过一个例子带领你一步一步地去实现它.让我们开始吧! 首先,我首必须决定我们将抓 ...
- MongDB/C# 杂项
1.MongDB的时间类型字段输出时为UTC的解决方法:保存到数据库中的数据还是按UTC存的,读出来的就按标识值读 [BsonDateTimeOptions(Kind = DateTimeKind.L ...
- iPhone手机安全指南
摘要:iPhone手机安全指南 - 1.iPhone解锁使用指纹:2.启用“查找我的iPhone”功能:3.Apple ID启用两步验证:4.修改SIM卡PIN码.5.iPhone被盗或丢失后,登录i ...
- windbg学习---!thread和.thread
!thread扩展显示目标系统中线程包括ETHREAD块在内的摘要信息.该命令只能在内核模式调试下使用 !thread [-p] [-t] [Address [Flags]] -p 显示拥有该线程的进 ...
- 深入理解js——作用域
"javaScript没有块级作用域",所谓"块",就是{}中间的内容.所以在声明变量的时候不要在"块"里面,要在一开始声明就好了. 其实j ...
- asp.net GDI+绘制五边形
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- [原创.数据可视化系列之五]韩国"萨德"系统防御图
自从7月8日美国和韩国共同宣布将在韩国部署萨德反导系统后,韩国国内对此事的巨大争议以及本地区一些国家的强烈不满情绪在持续发酵.“萨德”(THAAD)全称“末段高空区域防御系统”,是美国导弹防御局和美国 ...