java實現頁式儲存管理
阿新 • • 發佈:2019-01-24
基本框架
page.java
//page類
package pagedStorageManagement;
public class page {
private int pageNumber;//頁號
private int physicsNumber;//物理頁號
private boolean state;//狀態位
private int visitCount;//訪問欄位
private boolean change;//修改位
private int CRTAddress;//外存地址
public page()
{
this .pageNumber = -1;
this.physicsNumber = -1;
this.state = false;
this.visitCount = 0;
this.change = false;
this.CRTAddress = -1;
}
public page( int pageNumber, int physicsNumber, boolean state, int visitCount, boolean change, int CRTAddress)
{
this .pageNumber = pageNumber;
this.physicsNumber = physicsNumber;
this.state = state;
this.visitCount = visitCount;
this.change = change;
this.CRTAddress = CRTAddress;
}
public void setPageNumber( int pageNumber )
{
this.pageNumber = pageNumber;
}
public void setPhysicsNumber( int physicsNumber )
{
this.physicsNumber = physicsNumber;
}
public void setState (boolean state )
{
this.state=state;
}
public void setVisitCount( int visitCount )
{
this.visitCount = visitCount;
}
public void setChange( boolean change )
{
this.change = change;
}
public void setCRTAddress( int CRTAddress )
{
this.CRTAddress = CRTAddress;
}
public int getPageNumber( )
{
return this.pageNumber;
}
public int getPhysicsNumber()
{
return this.physicsNumber;
}
public boolean getState()
{
return this.state;
}
public int getVisitCount()
{
return this.visitCount;
}
public boolean getChange()
{
return this.change;
}
public int getCRTAddress()
{
return this.CRTAddress;
}
}
shell.java
//shell類
package pagedStorageManagement;
import java.util.Scanner;
public class shell {
page shell[];
private int current;
private int length;
public shell(){};
public shell( int length )
{
this.length = length;
this.current = 0;
shell = new page[length];
for( int i = 0; i < length ; i++ )
{
this.shell[i] = new page();
}
}
public void setCurrent( int current )
{
this.current = current;
}
public int getCurrent()
{
return this.current;
}
public int searchPage( int pageNumber )
{
int i = 0;
if( this.current == 0 )
{
return -2;
}
else
{
while( i < this.current )
{
if( this.shell[i].getPageNumber() == pageNumber )
{
return i;
}
i++;
}
return -1;
}
}
public void inChange( int b[], String ch, int number )
{
Scanner a = new Scanner( System.in );
switch( ch )
{
case "yes":
{
System.out.println("請輸入一個新的資料");
b[this.shell[number].getPhysicsNumber() ] = a.nextInt();
this.shell[number].setChange( true );
System.out.println("修改成功");
break;
}
case "no":
{
break;
}
default:
{
System.out.println("輸入字元有誤,將退出程式!");
System.exit(0);
}
}
}
public int isOver()
{
if( this.current >= this.length )
{
return 1;
}
else
return 0;
}
public int minVisitCount()
{
int i,t=0;
for (i=1; i<this.current; i++)
{
if( this.shell[i].getVisitCount() < this.shell[t].getVisitCount() )
{
t = i;
}
}
return t;
}
public int isChange( int number )
{
if( this.shell[number].getChange() == true )
{
return 1;
}
else
return 0;
}
public void printPageShell()
{
System.out.println("頁表:");
System.out.println("索引\t"+"頁號\t"+"物理塊號\t"+"狀態\t"+"訪問次數\t"+"修改\t"+"外存地址\t");
for( int i=0; i<this.length; i++ )
{
System.out.println(i+"\t"+this.shell[i].getPageNumber()+"\t"+this.shell[i] .getPhysicsNumber()+"\t"+this.shell[i].getState()+"\t"+this.shell[i].getVisitCount()+"\t"+this.shell[i].getChange()+"\t"+this.shell[i].getCRTAddress());
}
}
public void programFunction()
{
System.out.println("***********************請求分頁儲存系統***********************");
System.out.println("功能:");
System.out.println("\t 1.檢視頁表");
System.out.println("\t 2.檢視快表");
System.out.println("\t 3.檢視外存");
System.out.println("\t 4.在記憶體修改資料");
System.out.println("\t 5.繼續訪問頁面");
System.out.println("\t 6.退出程式");
}
public void dealFunction( int i, KShell TLB, source s[], int b[] )
{
if (i == 1 )
{
this.printPageShell();
}
else if ( i == 2)
{
TLB.printKShell();
}
else if ( i ==3 )
{
System.out.println("外存:");
System.out.println("外存地址\t"+"頁號\t"+"資料\n");
for (int k=0; k<20; k++)
{
s[k].printSource(k);
}
}
else if ( i == 4)
{
String ch = "yes";
int pageNumber;
Scanner a = new Scanner( System.in );
System.out.println("請輸入一個頁號:");
pageNumber = a.nextInt();
int number = this.searchPage( pageNumber );
if( number <0 )
{
System.out.println("記憶體中沒有此頁號");
}
else
{
this.inChange( b,ch,number );
}
}
else if ( i == 6)
{
System.out.println("結束程式");
System.exit(0);
}
}
public static void main( String[] args )
{
Scanner a = new Scanner( System.in );
int i,number = -10,k1,k2,result;
int k3 = 0;//當前儲存的記憶體地址
int t;//頁表中訪問次數最小的索引
int b[] = new int[10];//記憶體中儲存的資料
String ch;
int sLength,pLength,tLength,data;
System.out.println("請輸入外存大小:");
sLength = a.nextInt();
System.out.println("請輸入頁表大小:");
pLength = a.nextInt();
System.out.print("請輸入快表大小:");
tLength = a.nextInt();
//定義頁表,快表,外存
shell pageShell = new shell( pLength );//頁表
source s[] = new source[sLength];//外表
KShell TLB = new KShell( tLength );//快表
System.out.println("產生一個隨機序列作為外存資料!");
//錄入外存地址和資料
for( i = 0; i < sLength; i++ )
{
data = (int)( 100 * Math.random() );
System.out.print( data + "\t");
s[i] = new source( i, data );
}
System.out.println("\n外存設定成功");
//請求頁表
do
{
//TLB.printKShell();//列印當前快表的情況
//pageShell.printPageShell();//列印當前頁表的情況
System.out.println("請輸入一個頁面的頁號(0-19):");
k1 = a.nextInt();
if( k1 >= 20 || k1 < 0 )
{
System.out.println("輸入資料有錯,將退出程式!");
System.exit(0);
}
//檢測快表,快表儲存當前的頁表項,即當快表滿時採用最近最久未被使用演算法置換快表
System.out.println("進入快表檢測");
if( TLB.getCurrent() > 0 )
{
number = TLB.searchPage(k1);
if( number!=-1 && number!=-2 )
{
result = b[TLB.shell[number].getPhysicsNumber()];
System.out.println("在快表中找到,結果為:" + result );
//找出該頁號在頁表中的位置並修改訪問欄位
number = TLB.shell[number].getCRTAddress();
pageShell.shell[number].setVisitCount(pageShell.shell[number].getVisitCount()+1 );
}
}
if( TLB.getCurrent() <= 0 || number == -1 )
{
System.out.println("在快表中找不到!" + "進入記憶體檢測:");
//在快表中找不到,去記憶體區的頁表找
if( pageShell.current>0 )
{
number = pageShell.searchPage(k1);//頁號k1所在的下標
if( number !=-1 && number!=-2 )
{
result = b[pageShell.shell[number].getPhysicsNumber()];
System.out.println("在頁表中找到,結果為:" + result );
//修改訪問欄位和狀態位
pageShell.shell[number].setVisitCount(pageShell.shell[number].getVisitCount()+1);
//修改快表
TLB.changeKShell( pageShell,number );
}
}
if( pageShell.current <= 0 || number== -1 )
{
System.out.println("在記憶體中找不到!");
System.out.println("從外存中調入記憶體:");
//在頁表找不到,去外存區找
for( i=0; i<sLength ; i++ )
{
if( k1 ==s[i].getPageNumber() )//在外存找到了缺頁
{
k2 = pageShell.isOver();
if( k2 == 1 )//記憶體已滿
{
t = pageShell.minVisitCount();
System.out.println("記憶體已滿!即將調出頁號 " + pageShell.shell[t].getPageNumber());
}
else
{
t = pageShell.current;
pageShell.setCurrent( pageShell.getCurrent() + 1 );
}
//判斷是否修改了記憶體的資料
if( pageShell.isChange(t) == 1 )
{
s[pageShell.shell[t].getCRTAddress()].setSts(b[pageShell.shell[t].getPhysicsNumber()]);
}
//調入記憶體
pageShell.shell[t].setPageNumber(k1);
if( k2 == 1 )
{
b[pageShell.shell[t].getPhysicsNumber()] = s[i].getSts();
}
else
{
pageShell.shell[t].setPhysicsNumber(k3);//未滿則設定物理塊號,滿了只改變其他5個欄位
b[k3] = s[i].getSts();
k3++;//物理塊號
}
pageShell.shell[t].setState(true);
pageShell.shell[t].setVisitCount(1);
pageShell.shell[t].setChange(false);
pageShell.shell[t].setCRTAddress(i);
System.out.println("調入記憶體成功!");
//修改快表
TLB.changeKShell(pageShell,t);
System.out.println("修改快表成功!");
System.out.println("結果為:" + b[ k3-1 ]);
break;
}
}
}
}
do
{
pageShell.programFunction();
System.out.println("請輸入一個整數(1-6):");
i = a.nextInt();
while( i<1 || i>6 )
{
System.out.println("輸入有誤,請重新輸入(1-6):");
i = a.nextInt();
}
pageShell.dealFunction( i,TLB,s,b );
}while( i != 5 );
}while(i==5);
System.out.println("退出程式!");
}
}
KShell.java
//KShell類
package pagedStorageManagement;
public class KShell
{
page shell[];
private int current;
private int length;
private int changeNumber;//修改快表的次數
public KShell(){};
public KShell( int length )
{
this.length = length;
this.current = 0;
this.changeNumber = 0;
shell = new page[length];
for (int i=0; i<length; i++)
{
this.shell[i] = new page();
}
}
public void setCurrent( int current )
{
this.current = current;
}
public void setChangeNumber( int changeNumber )
{
this.changeNumber = changeNumber;
}
public int getCurrent()
{
return current;
}
public int getChangeNumber()
{
return changeNumber;
}
public int getLength()
{
return length;
}
public int searchPage( int pageNumber )
{
int i = 0;
if( this.changeNumber == 0 && this.current == 0 )
{
return -2;
}
else if( this.changeNumber < this.length )
{
while( i < this.current )
{
if( this.shell[i].getPageNumber() == pageNumber )
{
return i;
}
i++;
}
return -1;
}
else
{
while( i < this.length )
{
if( this.shell[i].getPageNumber() == pageNumber )
{
return i;
}
i++;
}
return -1;
}
}
public void changeKShell( shell pageShell, int number )
{
if( this.getChangeNumber() >= this.getLength() )
{
if ( this.getCurrent() == this.getLength() )
{
this.setCurrent(0);
}
System.out.println("快表已滿,快表中即將調出頁號" + this.shell[ this.current ].getPageNumber() );
}
if ( this.getCurrent() < this.getLength() )
{
this.shell[this.getCurrent()].setCRTAddress(number);
this.shell[this.getCurrent()].setPageNumber(pageShell.shell[number].getPageNumber());
this.shell[this.getCurrent()].setPhysicsNumber(pageShell.shell[number].getPhysicsNumber());
this.setCurrent( this.getCurrent()+1 );
this.setChangeNumber( this.getChangeNumber() + 1 );
}
}
public void printKShell()
{
System.out.println("快表:");
System.out.println("索引\t"+"頁號\t"+"物理塊號\t"+"在頁表下的索引");
for( int i=0; i<this.length; i++ )
{
System.out.println( i + "\t" + this.shell[i].getPageNumber() + "\t" + this.shell[i] .getPhysicsNumber() + "\t" + this.shell[i].getCRTAddress() );
}
}
}
source.java
//source類
package pagedStorageManagement;
public class source {
private int pageNumber;//頁號
private int sts;//資料
private int length;
public source(){};
public source( int pageNumber , int sts )
{
this.pageNumber = pageNumber;
this.sts = sts;
}
public void setPageNumber( int pageNumber )
{
this.pageNumber = pageNumber;
}
public void setSts( int sts )
{
this.sts = sts;
}
public int getPageNumber()
{
return pageNumber;
}
public int getSts()
{
return sts;
}
public void printSource( int i )
{
System.out.println( i + "\t" + this.pageNumber + "\t" + this.sts + "\n" );
}
}
使用說明
本程式是使用java語言編寫的實現請求分頁儲存管理的程式,是在eclipise下執行的結果,只需執行Shell類就行了。
首先先設定外存,頁表和快表的大小,然後輸入一個請求訪問的頁面。
測試樣例