一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号,从0开始,如第0页、第1页等。把内存空间分成与页面相同大小的若干个存储块,称为(物理)块或页框,同样进行编号。在为进程分配内存时,以块为单位将进程中的若干个页分别装入到多个可以不相邻接的物理块中。 为了标识中哪些块空闲,哪些块占用,可用一张位示图指示。位示图是由若干主存单元构成,如图4-1所示。其中每一位与一个主存块对应。分别用0和1表示对应块是空闲还是占用。 在装入一个作业时,根据作业对主存的需求量,先检查是否有足够的空闲块,如有,则查位示图,按作业需求量找出为0的一些位,且置上占用标记1。 按找到的位计算对应的块号。其计算公式为: 块号=J*8+I 其中,J表示找到的字节号,I表示找到的位号。
首先我们构造页面类,代码如下:
package 页式存储;
public class Page {
private int PageNumber; //页面号
private int BlockNumber; //即将存储它的块号
public Page(int pageNumber) { //构造方法
super();
PageNumber = pageNumber;
}
public int getBlockNumber() {
return BlockNumber;
}
public void setBlockNumber(int blockNumber) {
BlockNumber = blockNumber;
}
public int getPageNumber() {
return PageNumber;
}
public void Print(){
System.out.print(this.PageNumber+" "+this.BlockNumber);
}
}
之后进行设计位示图算法,代码如下:
package 页式存储;
import java.util.Random;
import java.util.Scanner;
public class Block{
private int[][] BitMap; //位示图数组
public Block(int n) { //构造方法
super();
BitMap = new int[n][16];
for ( int i = 0 ; i < n ; i++){
BitMap[i] = this.Random_MakeBitMap();
}
}
public int[] getBitMap(int index) { //按index寻找位示图
return BitMap[index];
}
public int[] Random_MakeBitMap(){ //随机初始化位示图
Random r = new Random();
int[] bitmap = new int[16];
for ( int i = 0 ; i < 16 ; i++){
float flag = r.nextFloat();
if ( flag <= 0.3){
bitmap[i] = 1;
}else{
bitmap[i] = 0;
}
}
return bitmap;
}
public int FindNotBusy(int index){ //寻找空闲的块
int index_notbusy = 0;
for ( int i = 0 ; i < 16 ; i++){
if ( this.BitMap[index][i] == 0){
index_notbusy = i;
break;
}
}
return index_notbusy;
}
public void StorePage(Page p){ //存储页面
int index = FindNotBusy(p.getBlockNumber());
this.BitMap[p.getPageNumber()][index] = 1;
p.setBlockNumber(p.getPageNumber() * 8 + index);
}
public void ReleasePage(Page p){ //释放页面
int index = p.getBlockNumber() - p.getPageNumber() * 8;
this.BitMap[p.getPageNumber()][index] = 0;
p.setBlockNumber(0);
}
public void Print(Page p){ //打印信息
p.Print();
System.out.print(" ");
for ( int i = 0 ; i < 16 ; i++){
System.out.print(this.BitMap[p.getPageNumber()][i]);
}
System.out.println();
}
public void Print_BitMap(){ //打印位示图数组
for ( int i = 0 ; i < this.BitMap.length ; i++){
for ( int j = 0 ; j < 16 ; j++){
System.out.print(this.BitMap[i][j]);
}
System.out.println();
}
}
public static void main(String[] args0){
Scanner in = new Scanner(System.in);
System.out.print("需要初始化的页面有:");
int num = in.nextInt();
Page[] page = new Page[num];
for ( int i = 0 ; i < num ; i++){
page[i] = new Page(i);
}
Block block = new Block(num);
System.out.println("------------------------开始存储页面-------------------------");
System.out.println("存储前的位示图:");
for ( int i = 0 ; i < num ; i++){
block.Print(page[i]);
}
for ( int i = 0 ; i < num ; i++){
block.StorePage(page[i]);
}
System.out.println("页面号"+" "+"块号"+" "+"位示图");
for ( int i = 0 ; i < num ; i++){
block.Print(page[i]);
}
System.out.println("------------------------开始释放页面-------------------------");
System.out.println("释放前的位示图:");
block.Print_BitMap();
for ( int i = 0 ; i < num ; i++){
block.ReleasePage(page[i]);
}
System.out.println("释放后的位示图:");
block.Print_BitMap();
in.close();
}
}