设计目的:
加深对请求页式存储管理实现原理的理解,掌握页面置换算法。
设计内容:
设计一个程序,有一个虚拟存储区和内存工作区,实现下述三种算法中的任意两种,计算访问命中率(命中率=1-页面失效次数/页地址流长度)。附加要求:能够显示页面置换过程。
import java.util.Scanner;
import java.util.Random;
public class QQ {
public static void main(String[] args) {
int Input;
Scanner input = new Scanner(System.in);
System.out.println("请选择下面两种算法中的一种: 1.先进先出 2.最近未使用算法");
Input = input.nextInt();
switch(Input){
case 1:
FIFO f = new FIFO();
f.way();
break;
case 2:
LRU l = new LRU();
l.way();
break;
default:
System.out.println("非法输入");
break;
}
}
}
class FIFO{
void way() {
int i,j;
int m = 0;
int n = 0;
int Maxflag = 0;
int Max = -1;
int count = 0;//缺页数
int Num1,Num2;
double QYL;
double MZL;
System.out.print("请输入进程数:");
Random rand = new Random();
Scanner a = new Scanner(System.in);
Num1 = a.nextInt();
JJ page[] = new JJ[Num1];
System.out.println("产生的随机进程序列如下:");
for(i = 0; i < Num1; i++) {
page[i] = new JJ();
page[i].num = rand.nextInt(10) + 1 ;
}
for(i = 0; i < Num1; i++){
System.out.print(page[i].num+" ");
}
System.out.println();
System.out.print("请输入内存块数:");
Num2 = a.nextInt();
NC nc[] = new NC[Num2];
for(i = 0; i < Num2; i++) {
nc[i] = new NC();
nc[i].phb = 0;
nc[i].flag = 0;
}
System.out.println("现在在内存中的进程编号为:");
for(i = 0; i < Num2; i++)
{
System.out.print(nc[i].phb+" ");
}
System.out.println();
for(j = 0; j < Num1; j++){
NC c = new NC();
m = c.searchphb(nc,Num2);
n = c.searchpro(page,Num1,nc,Num2,j);
for(i = 0; i < Num2; i++)
{
if(nc[i].flag>Maxflag)
{
Maxflag = nc[i].flag;
Max = i;
}
}
if(n == -1) //不存在相同进程
{
if(m != -1) //存在空闲物理块
{
nc[m].phb = page[j].num; //进程号填入该空闲物理块
count++;
nc[m].flag = 0;
for(i = 0;i <= m; i++)
{
nc[i].flag++;
}
m = -1;
}
else //不存在空闲物理块
{
nc[Max].phb = page[j].num;
nc[Max].flag = 0;
for(i = 0;i < Num2; i++)
{
nc[i].flag++;
}
Max = -1;
Maxflag = 0;
count++;
}
}
else //存在相同的进程
{
nc[n].phb = page[j].num;
for(i = 0;i < Num2; i++)
{
nc[i].flag++;
}
n = -1;
}
System.out.println("现在在内存中的进程编号为:");
for(i = 0; i < Num2; i++)
{
System.out.print(nc[i].phb+" ");
}
System.out.println();
}
QYL = (double)count/Num1;
MZL = 1 - QYL;
System.out.println("缺页次数为:"+count);
System.out.println("缺页率为:"+QYL);
System.out.println("命中率为:"+MZL);
}
}
class LRU{
void way() {
int i,j;
int m = 0;
int n = 0;
int MaxTime = 0;
int Max = -1;
int count = 0;//缺页数
int Num1,Num2;
double QYL;
double MZL;
System.out.print("请输入进程数:");
Random rand = new Random();
Scanner a = new Scanner(System.in);
Num1 = a.nextInt();
JJ page[] = new JJ[Num1];
System.out.println("产生的随机进程序列如下:");
for(i = 0; i < Num1; i++) {
page[i] = new JJ();
page[i].num = rand.nextInt(10) + 1 ;
}
for(i = 0; i < Num1; i++){
System.out.print(page[i].num+" ");
}
System.out.println();
System.out.print("请输入内存块数:");
Num2 = a.nextInt();
NC nc[] = new NC[Num2];
for(i = 0; i < Num2; i++) {
nc[i] = new NC();
nc[i].phb = 0;
nc[i].flag = 0;
}
System.out.println("现在在内存中的进程编号为:");
for(i = 0; i < Num2; i++)
{
System.out.print(nc[i].phb+" ");
}
System.out.println();
for(j = 0; j < Num1; j++){
NC c = new NC();
m = c.searchphb(nc,Num2);
n = c.searchpro(page,Num1,nc,Num2,j);
for(i = 0; i < Num2; i++)
{
if(nc[i].time > MaxTime)
{
MaxTime = nc[i].time;
Max = i;
}
}
if(n == -1) //不存在相同进程
{
if(m != -1) //存在空闲物理块
{
nc[m].phb = page[j].num; //进程号填入该空闲物理块
count++;
nc[m].time = 0;
for(i = 0;i <= m; i++)
{
nc[i].time++;
}
m = -1;
}
else //不存在空闲物理块
{
nc[Max].phb = page[j].num;
nc[Max].time = 0;
for(i = 0;i < Num2; i++)
{
nc[i].time++;
}
Max = -1;
MaxTime = 0;
count++;
}
}
else //存在相同的进程
{
nc[n].phb = page[j].num;
nc[n].time = 0;
for(i = 0;i < Num2; i++)
{
nc[i].time++;
}
n = -1;
}
System.out.println("现在在内存中的进程编号为:");
for(i = 0; i < Num2; i++)
{
System.out.print(nc[i].phb+" ");
}
System.out.println();
}
QYL = (double)count/Num1;
MZL = 1 - QYL;
System.out.println("缺页次数为:"+count);
System.out.println("缺页率为:"+QYL);
System.out.println("命中率为:"+MZL);
}
}
class JJ{
int num;//记录页面号
}
class NC{
int phb;//内存块
int flag;
int time;//记录调入内存时间
int searchphb(NC nc[],int Num2) {
int i;//查找空闲物理块
int m = 0;
for(i = 0; i < Num2; i++) {
if(nc[i].phb == 0) {
m = i;
break;
}
}
if(i < Num2)
return m;
return -1;
}
int searchpro(JJ page[],int Num1,NC nc[],int Num2,int j) { //查找是否有相同进程块
int i;
int n = 0;
for(i = 0; i < Num2; i++){
if(page[j].num == nc[i].phb){
n = i;
break;
}
}
if(i < Num2)
return n;
return -1;
}
}