请求页式存储管理中页面置换算法的java实现

时间:2024-03-18 15:20:39

        存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。
        模拟页式虚拟存储管理中硬件的地址转换和缺页中断,并用先进先出调度算法(FIFO)处理缺页中断。
        (1)为了装入一个页面而必须调出一页时,如果被选中调出的页面在执行中没有修改过,则不必把该页重新写到磁盘上(因磁盘上已有副本)。因此,在页表中可以增加是否修改过的标志,当执行“存”指令、“写”指令时把对应页的修改标志置成“1”表示该页修改过,否则为“0”表示该页未修改过。页表格式如表3-1所示。

请求页式存储管理中页面置换算法的java实现

        (2)设计一个地址转换程序来模拟硬件的地址转换和缺页中断。当访问的页在主存时则形成绝对地址,但不去模拟指令的执行,可用输出转换后的绝对地址来表示一条指令已完成。当访问的页不在主存时则输出“*该页页号”来表示硬件产生了一次缺页中断。模拟地址转换的程序流程如图3-1所示。

请求页式存储管理中页面置换算法的java实现

        (3)编制一个FIFO页面调度程序。FIFO页面调度算法总是先调出作业中最先进入主存的那一页,因此,可以用一个数组来构成页号队列。数组中每个元素是该作业已在主存的页面号,假定分配给作业的主存块数为m,且该作业开始的m页已装入主存,则数组可由m个元素组成:
P[0],P[1],…,P[m-1]
它们的初值为
P[0]∶=0,P[1]∶=1,…,P[m-1]∶= m-1
用一指针k指示当要装入新页时应调出的页在数组的位置,k的初值为“0”。

        当产生缺页中断后,操作系统总是选择P[k]所指出的页面调出,然后执行
P[k]∶=要装入的新页页号
k∶=(k+1)mod m
在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入的过程。模拟程序的流程见图3-1。
        (4)假定主存的每块长度为1024个字节,现有一个共7页的作业,其副本已在磁盘上。系统为该作业分配了4块主存块,且该作业的第0页至第3页已经装入主存,其余3页尚未装入主存,该作业的页表见表3-2。

请求页式存储管理中页面置换算法的java实现

如果该作业依次执行的指令序列如表3-3所示。

请求页式存储管理中页面置换算法的java实现

        依次执行上述的指令序列来调试你所设计的程序(仅模拟指令的执行,不必考虑指令序列中具体操作的执行)
        (5)为了检查程序的正确性,可自行确定若干组指令序列,运行设计的程序,核对执行结果。

主类

package report;

import java.util.ArrayList;
import java.util.List;

public class N3 {

	private static int L;
	private static int j;
	private static int m = 4;
	private static int k = 0;
	private static int P[] = { 0, 1, 2, 3 };

	private static List<Page> pageList = new ArrayList<Page>();
	private static List<Cmd> cmdList = new ArrayList<Cmd>();

	public static void main(String[] args) {

		Page page0 = new Page(0, 1, 5, 0, "011");
		Page page1 = new Page(1, 1, 8, 0, "012");
		Page page2 = new Page(2, 1, 9, 0, "013");
		Page page3 = new Page(3, 1, 1, 0, "021");
		Page page4 = new Page(4, 0, -1, 0, "022");
		Page page5 = new Page(5, 0, -1, 0, "023");
		Page page6 = new Page(6, 0, -1, 0, "121");
		pageList.add(page0);
		pageList.add(page1);
		pageList.add(page2);
		pageList.add(page3);
		pageList.add(page4);
		pageList.add(page5);
		pageList.add(page6);
		Cmd cmd0 = new Cmd("+", 0, "070");
		Cmd cmd1 = new Cmd("+", 1, "050");
		Cmd cmd2 = new Cmd("x", 2, "015");
		Cmd cmd3 = new Cmd("存", 3, "021");
		Cmd cmd4 = new Cmd("取", 0, "056");
		Cmd cmd5 = new Cmd("-", 6, "040");
		Cmd cmd6 = new Cmd("移位", 4, "053");
		Cmd cmd7 = new Cmd("+", 5, "023");
		Cmd cmd8 = new Cmd("存", 1, "037");
		Cmd cmd9 = new Cmd("取", 2, "078");
		Cmd cmd10 = new Cmd("+", 4, "001");
		Cmd cmd11 = new Cmd("存", 6, "084");
		cmdList.add(cmd0);
		cmdList.add(cmd1);
		cmdList.add(cmd2);
		cmdList.add(cmd3);
		cmdList.add(cmd4);
		cmdList.add(cmd5);
		cmdList.add(cmd6);
		cmdList.add(cmd7);
		cmdList.add(cmd8);
		cmdList.add(cmd9);
		cmdList.add(cmd10);
		cmdList.add(cmd11);
		printPageList();
		while (!cmdList.isEmpty()) {
			// 取指令中访问的页号=>L
			L = cmdList.get(0).getPage();

			while (true) {
				// 查页表
				// 页标志=1
				if (pageList.get(L).getFlag() == 1) {
					// 形成绝对地址
					int absoluteAddress = pageList.get(L).getPiece() * 1024
							+ Integer.parseInt(cmdList.get(0).getAddressInPage());

					// 是”存”指令
					if (cmdList.get(0).getOperation().equalsIgnoreCase("存")) {
						// 置L页修改标志”1”
						pageList.get(L).setModify(1);

					} else {
					}

					// 输出绝对地址
					System.out.println("运行指令:" + cmdList.get(0).getOperation() + "\t页号:" + pageList.get(L).getPage()
							+ "        页内地址:" + cmdList.get(0).getAddressInPage() + "        绝对地址:" + absoluteAddress
							+ "        页标志:" + pageList.get(L).getFlag() + "        主存块号:" + pageList.get(L).getPiece()
							+ "        页修改标志:" + pageList.get(L).getModify() + "        页在磁盘上的位置:"
							+ pageList.get(L).getPositionInDisk());

				}
				// 页标志!=1
				else {
					System.out.println();
					System.out.println("内存中找不到页" + L);

					j = P[k];
					int tempPiece = pageList.get(j).getPiece();

					if (pageList.get(j).getModify() == 1) {
						System.out.println("页" + 3 + "写到外存");
					} else {
					}
					System.out.println("内存调出页" + j);
					pageList.get(j).setFlag(0);
					pageList.get(j).setModify(0);
					pageList.get(j).setPiece(-1);
					System.out.println("内存调入页" + L);
					pageList.get(L).setFlag(1);
					pageList.get(L).setPiece(tempPiece);
					P[k] = L;
					k = (k + 1) % m;
					printPageList();
					continue;
				}
				// 当前指令结束
				cmdList.remove(0);
				break;
			}
		}
	}

	private static void printPageList() {
		System.out.println("==========================================================================");
		System.out.print("页号\t标志\t主存块号\t修改标志\t在磁盘上的位置\n");
		// finish链
		for (Page page : pageList)
			System.out.println(page.getPage() + "\t" + page.getFlag() + "\t" + page.getPiece() + "\t" + page.getModify()
					+ "\t" + page.getPositionInDisk());
		System.out.println("==========================================================================");

	}
}

page类

package report;

public class Page {
	private int page;
	private int flag;
	private int piece;
	private int modify;
	private String positionInDisk;

	public Page(int page, int flag, int piece, int modify, String positionInDisk) {

		this.page = page;
		this.flag = flag;
		this.piece = piece;
		this.modify = modify;
		this.positionInDisk = positionInDisk;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getFlag() {
		return flag;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	public int getPiece() {
		return piece;
	}

	public void setPiece(int piece) {
		this.piece = piece;
	}

	public int getModify() {
		return modify;
	}

	public void setModify(int modify) {
		this.modify = modify;
	}

	public String getPositionInDisk() {
		return positionInDisk;
	}

	public void setPositionInDisk(String positionInDisk) {
		this.positionInDisk = positionInDisk;
	}

}

 运行过程部分截图

请求页式存储管理中页面置换算法的java实现