一、實驗內容
編程實現首次適應與循環首次適應算法。
二、實驗要求
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;
}
}
五、實驗總結
通過本次實驗我更加了解了循環首次適應與首次適應算法,首次適應算法優先利用低地址部分空閑分區,保留了高地址部分的大空閑區,缺點是低址部分不斷被划分,會留下很多難以利用的小的外部碎片,每次都從低地址部分開始查會增加查找時的開銷。
循環首次適應算法不再是每次從鏈首開始查找,而是從上次找到的空閑分區的下一個空閑分區開始查找,如果最后一個空閑分區大小不能滿足要求返回到鏈首,若從鏈首到鏈尾都找不到滿足要求的空閑分區則分配失敗。該算法能是內存中的空閑分區分布的更均勻,從而減小了查找空閑分區時的開銷,但這樣會缺乏大的空閑分區。