内存管理-请求分页分配方式-设计方案报告
文末有源码
文章目录
1. 项目需求
1.1 基本任务
假设每个页面可存放10条指令,分配给一个作业的内存块为4。模拟一个作业的执行过程,该作业有320条指令,即它的地址空间为32页,目前所有页还没有调入内存。
1.2 功能描述
-
在模拟过程中,如果所访问指令在内存中,则显示其物理地址,并转到下一条指令;如果没有在内存中,则发生缺页,此时需要记录缺页次数,并将其调入内存。如果4个内存块中已装入作业,则需进行页面置换。
-
所有320条指令执行完成后,计算并显示作业执行过程中发生的缺页率。
-
置换算法可以选用FIFO或者LRU算法
-
作业中指令访问次序可以按照下面原则形成:
50%的指令是顺序执行的,25%是均匀分布在前地址部分,25%是均匀分布在后地址部分
1.3 项目目的
- 理解页面、页表、地址转换
- 体会页面置换过程
- 加深对请求调页系统的原理和实现过程的理解。
2. 开发环境
- 开发环境: Windows 10
- 开发软件: Eclipse
- 开发语言: JavaSE (jdk1.8.0_241)
- 开发工具包: Swing
3. 项目结构
│ memory.exe
│ memory.jar
│ README.md
│ 内存管理 - 请求分页分配方式模拟.md
│ 内存管理 - 请求分页分配方式模拟.pdf
│
└─src
├─Component
│ AlgSelectBar.java
│ Block.java
│ EventListener.java
│ Memory.java
│ Moniter.java
│ Page.java
│ SpeedSlider.java
│ WaitingList.java
│
└─UI
MainFrame.java│ memory.jar
│ memory.exe
│ README.md
│ 请求分区分配方式模拟_设计方案报告.md
│ 请求分区分配方式模拟_设计方案报告.pdf
│
└─src
├─component
│ AlgSelectBar.java
│ Block.java
│ EventListener.java
│ Memory.java
│ Moniter.java
│ Page.java
│ SpeedSlider.java
│ WaitingList.java
└─UI
MainFrame.java
4. 操作说明
-
双击目录下的
memory.jar
(或memory.exe
)文件进入模拟界面-
点击exe文件可能出现如下警告 -> 点击确定即可
-
-
在右上角的选项条中选择置换算法
- FIFO-先进先出算法(默认值)
- LRU-最近最少使用页面淘汰算法
-
点击开始模拟
-
滑动调节速度的滑块可以调整模拟速度
- 慢速条件下可以看清模拟调页的过程
- 快速条件下可以快速得到最终的结果——缺页率
-
点击数据清零可以清除本轮模拟产生的数据以进行下一轮模拟
5. 系统分析
5.1 置换算法
5.1.1 FIFO算法
- 当前页面已经在内存中 => 不需要进行调度,直接显示指令所在地址
- 当内存中页面数小于分配给一个进程的内存容量(4页) 时 => 直接将页面顺序加入到内存的空闲块中,然后显示指令所在地址
- 当内存满时 => 每次替换掉最早进入内存块中的逻辑页面
- 维护一个变量
turn
,每次执行一条指令,turn就自增1、模4,用来指定调出哪一块物理页中的逻辑页turn==0
调出0号页面中的内容,将需要用的页调入物理0页turn==1
调出1号页面中的内容,将需要用的页调入物理1页turn==2
调出2号页面中的内容,将需要用的页调入物理2页turn==3
调出3号页面中的内容,将需要用的页调入物理3页
- 维护一个变量
5.1.2 LRU算法
- 当前页面已经在内存中 => 不需要进行调度,直接显示指令所在地址
- 当内存中页面数小于分配给一个进程的内存容量(4页) 时 => 直接将页面顺序加入到内存的空闲块中,然后显示指令所在地址
- 当内存满时 => 每次替换掉最近最少使用的内存块中的页面
- 用一个数组记录每个物理页的空闲次数
- 每执行一条指令,未用到的物理页对应的空闲次数加一
- 被执行到的指令所在的物理页空闲次数清零
- 当遇到需要调页的情况时,选取空闲次数最多的页将其调出,将需要用到的页调入,并置该页的空闲次数为0,其余加一
- 用一个数组记录每个物理页的空闲次数
5.2 指令产生方式
为了保证320条指令能够随机产生、均匀分布,模拟过程采用了下面这种循环产生指令的方式:
- 在0~319条指令之间,随机选取一个起始执行指令,如序号为 m m m
- 顺序执行下一条指令,即序号为 m + 1 m+1 m+1的指令
- 通过随机数,跳转到前地址部分0~ ( m − 1 ) (m-1) (m−1)中的某个指令处,其序号为 m 1 m_1 m1
- 若前面已经没有尚未执行的指令,则在全局范围内产生随机数,直到找到一个还未执行的指令
- 顺序执行后面第一条未执行的指令,即序号为 m 1 m_1 m1+n的指令
- 通过随机数,跳转到后地址部分 ( m 1 + n + 1 ) (m_1+n+1) (m1+n+1)~319中的某条指令处,其序号为 m 2 m_2 m2
- 若后面已经没有尚未执行的指令,则在全局范围内产生随机数,直到找到一个还未执行的指令
- 顺序执行后面第一条未执行的指令,即序号为 m 2 + n m_2+n m2+n的指令
- 重复3~7的步骤直到执行完320条指令
6. 系统设计
6.1 类设计
6.1.1 算法选择条(AlgSelectBar)
6.1.2 页内代码块(Block)
public class Block extends JLabel {
public Block() {
setLayout(null);//设置布局方式
setText("NULL");//设置初始文字
setHorizontalAlignment(SwingConstants.CENTER);
this.setBackground(new Color(88,201,185));
setOpaque(true);
setForeground(Color.white);
setFont(new Font("楷体", Font.BOLD, 20));
}
}
6.1.3 事件监听(EventListener)
public class EventListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("I'm listening!");
}
}
6.1.4 内存(Memory)
6.1.4.1 调度算法(dispatchPage)
public void dispatchPage(int physicPage, int logicalPage) {
this.pages[physicPage].change(logicalPage);
}