1. 程式人生 > >java實現頁式儲存管理

java實現頁式儲存管理

123.png

基本框架

螢幕快照 2017-11-24 12.41.42.png

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類就行了。
首先先設定外存,頁表和快表的大小,然後輸入一個請求訪問的頁面。

測試樣例

螢幕快照 2017-11-24 12.52.04.png
螢幕快照 2017-11-24 12.53.05.png
螢幕快照 2017-11-24 12.53.26.png
螢幕快照 2017-11-24 12.53.43.png

原始碼下載