首次适应与循环首次适应算法实现
一、实验内容
编程实现首次适应与循环首次适应算法。
二、实验要求
1.任选一种高级语言实现;
三、实验过程
1、 设计思想
首次适应算法(FF):将所有空闲分区按照地址递增的次序链接,在申请内存分配时,从链首开始查找,将满足需求的第一个空闲分区分配给作业。
循环首次适应算法(NF):将所有空闲分区按照地址递增的次序链接,在申请内存分配时,总是从上次找到的空闲分区的下一个空闲分区开始查找,将满足需求的第一个空闲分区分配给作业
2、 数据结构
public class FreeArea {
private int address;//内存地址
private int size;//空闲区大小
public FreeArea() {
}
public FreeArea(int address, int size) {
this.address = address;
this.size = size;
}
public int getAddress() {
return address;
}
public void setAddress(int address) {
this.address = address;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
4、
运行结果:
四、实验代码
RR.H
package com.hu;
import java.util.Scanner;
public class MemoAlloc {
public static void main(String[] args) {
System.out.println("======首次适应算法======");
FreeArea freeArea[]= init();
FF(freeArea);
System.out.println("=====循环首次适应算法=====");
FreeArea freeArea1[]= init();
NF(freeArea1);
}
public static void FF(FreeArea freeArea[]){//首次适应算法
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要分配的内存大小:");
int size = scanner.nextInt();
for (int i =0;i<freeArea.length;i++){
if (size<=freeArea[i].getSize()){//若分配内存大小小于空闲分区大小则分配成功
System.out.println("分配内存成功");
freeArea[i].setSize(freeArea[i].getSize()-size);//修改空闲分区大小
break;
}if (i== freeArea.length-1&&size>freeArea[i].getSize()) System.out.println("分配失败");
}
}
public static void NF(FreeArea freeArea[]){//循环首次适应
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要分配的内存大小:");
int size = scanner.nextInt();
boolean isWhile=true;
int ProcessNum =0;
int j=0;
for (int i=ProcessNum;i< freeArea.length;i++,j++){
if (size <= freeArea[i].getSize() ) {//若分配内存大小小于空闲分区大小则分配成功
System.out.println("分配内存成功");
freeArea[i].setSize(freeArea[i].getSize() - size);
ProcessNum = j+1;//下一次查找时从本次找到的空闲分区的下一个分区开始找
break;
}else if (ProcessNum!=0 && i== freeArea.length-1&&size>freeArea[i].getSize()){
ProcessNum=0;//若开始查找时不是从链首开始,最后一个空闲分区大小仍不能满足要求,则返回第一个空闲分区
}else if(ProcessNum==0&&i== freeArea.length-1&&size>freeArea[i].getSize()){
System.out.println("分配失败");//若开始查找时是从链首开始,最后一个空闲分区大小仍不能满足要求,则分配失败
};
}
}
public static FreeArea[] init(){//空闲区初始化并排序
System.out.println("初始化空闲区并分配内存地址与大小");
Scanner scanner = new Scanner(System.in);
FreeArea[] freeAreas = new FreeArea[5];
for (int i=0;i<freeAreas.length;i++){
System.out.println("请输入内存地址与大小:");
freeAreas[i] = new FreeArea(scanner.nextInt(),scanner.nextInt());
}
FreeArea t;
for (int i = 0;i<freeAreas.length;i++){
for (int j = 0;j<freeAreas.length-1;j++){
if(freeAreas[j].getAddress()>freeAreas[j+1].getAddress()){
t = freeAreas[j+1];
freeAreas[j+1]=freeAreas[j];
freeAreas[j]=t;
}
}
}
return freeAreas;
}
}
五、实验总结
通过本次实验我更加了解了循环首次适应与首次适应算法,首次适应算法优先利用低地址部分空闲分区,保留了高地址部分的大空闲区,缺点是低址部分不断被划分,会留下很多难以利用的小的外部碎片,每次都从低地址部分开始查会增加查找时的开销。
循环首次适应算法不再是每次从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,如果最后一个空闲分区大小不能满足要求返回到链首,若从链首到链尾都找不到满足要求的空闲分区则分配失败。该算法能是内存中的空闲分区分布的更均匀,从而减小了查找空闲分区时的开销,但这样会缺乏大的空闲分区。