首次适应算法:
使用该算法进行内存分配时,从空闲分区链首开始查找,直至找到一个能满足其大小需求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。
该算法倾向于使用内存中低地址部分的空闲分区,在高地址部分的空闲分区非常少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。缺点在于低址部分不断被划分,留下许多难以利用、非常小的空闲区,而每次查找又都从低址部分开始,这无疑会增加查找的开销。
首次适应算法的具体代码实现:
数据结构:我们将计算机的内存地址抽象为一个链表,链表的节点包括首地址、内存大小、和当前的状态(是否被使用)。每进程则用进程类实例化的对象来表示;进程中的属性有进程名以及进程所需内存的大小;
具体代码实现:
进程类:
public class Process {
String pName; //作业号
int pSize; //作业大小
public String getpName() {
return pName;
}
public void setpName(String pName) {
this.pName = pName;
}
public int getpSize() {
return pSize;
}
public void setpSize(int pSize) {
this.pSize = pSize;
}
}
算法接口类:
public interface DynamicStoreAlgorithm {
void init(int size); //初始化分区链表
boolean allocatePartition(Process process); //分配分区
boolean recoverPartition(Process process); //回收分区
void unitPartition(MNode mnode); //合并空闲分区
void show(); //显示当前的内存状态
}
接口实现类:
public class DynamicStoreAlgorithmImpl implements DynamicStoreAlgorithm{
private MNode mHeadNode;
public DynamicStoreAlgorithmImpl(){
mHeadNode = new MNode();
}
@Override
public boolean allocatePartition(Process process) {
// TODO Auto-generated method stub
boolean flag = false;
MNode Node = mHeadNode;
while(Node.getNextNode() != null){
Node = Node.getNextNode();
if(Node.getSize()>process.getpSize()){ //当进程所需的大小小于空闲内存分区时;
flag = true;
//申请新的内存空间,并进行初始化
MNode mNode = new MNode();
mNode.setSize(process.getpSize());
mNode.setStartIndex(Node.getStartIndex());
mNode.setFree(false);
mNode.setProcessName(process.getpName());
//修改原来结点的数据结构
Node.setSize(Node.getSize()-process.getpSize());
Node.setStartIndex(Node.getStartIndex()+process.getpSize());
//改变当前链表指针的指向
MNode m = Node.getPreNode();
mNode.setPreNode(m);
Node.getPreNode().setNextNode(mNode);
Node.setPreNode(mNode);
mNode.setNextNode(Node);
break;
}else if(Node.getSize()== process.getpSize()){
flag = true;
Node.setProcessName(process.getpName());
Node.setFree(false);
break;
}
}
//若flag为真,则找到分区分配给进程;若为假则没有适当的空闲分区可以分配给该进程
if(flag){
return true;
}
else
return false;
}
@Override
public void init(int size) {
// TODO Auto-generated method stub
MNode mNode = new MNode();
mNode.setNextNode(null);
mNode.setPreNode(mHeadNode);
mNode.setStartIndex(0);
mNode.setSize(size);
mNode.setFree(true);
mHeadNode.setPreNode(null);
mHeadNode.setNextNode(mNode);
}
@Override
public boolean recoverPartition(Process process) {
// TODO Auto-generated method stub
boolean flag = false;
MNode node = mHeadNode;
while(node.getNextNode()!= null){
node = node.getNextNode();
if(node.getProcessName()!=null && node.getProcessName().equals(process.getpName())){
node.setFree(true);
node.setProcessName(null);
unitPartition(node);
flag=true;
break;
}
}
return flag;
}
@Override
public void unitPartition(MNode mnode) {
// TODO Auto-generated method stub
MNode preNode = mnode.getPreNode();
MNode nextNode = mnode.getNextNode();
if(preNode.isFree()&&nextNode.isFree()){
int size = preNode.getSize()+mnode.getSize()+nextNode.getSize();
preNode.setSize(size);
preNode.setNextNode(nextNode.getNextNode());
}else if(!preNode.isFree() && nextNode.isFree()){
int size = mnode.getSize()+nextNode.getSize();
mnode.setSize(size);
mnode.setNextNode(nextNode.getNextNode());
}else if(preNode.isFree() && !nextNode.isFree()){
int size = preNode.getSize()+mnode.getSize();
preNode.setSize(size);
preNode.setNextNode(nextNode);
}
}
@Override
public void show() {
// TODO Auto-generated method stub
MNode node = mHeadNode;
System.out.println("分区号"+"\t"+"开始地址"+"\t"+"分区大小"+"\t"+"状态(t空 f忙)"+"\t"+"运行进程");
int i=1;
while(node.getNextNode()!= null){
node = node.getNextNode();
System.out.println(i+"\t"+node.getStartIndex()+"\t"+node.getSize()+"\t"+node.isFree()+"\t\t"+node.getProcessName());
i++;
}
}
}
结点类:
package hwchao.algorithm;
public class MNode {
private String processName; //正在使用的进程号
private MNode preNode; //前驱结点
private MNode nextNode; //后继结点
private int startIndex; //开始地址
private boolean free; //分区状态 1.true表示空闲 2.false表示使用
private int size; //分区大小
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public MNode getPreNode() {
return preNode;
}
public void setPreNode(MNode preNode) {
this.preNode = preNode;
}
public MNode getNextNode() {
return nextNode;
}
public void setNextNode(MNode nextNode) {
this.nextNode = nextNode;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public boolean isFree() {
return free;
}
public void setFree(boolean free) {
this.free = free;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
主方法:
import java.util.Scanner;
import hwchao.algorithm.Process;
import hwchao.algorithm.DynamicStoreAlgorithmImpl;
public class Main {
static Scanner input = new Scanner(System.in);
public static void main(String[] args){
DynamicStoreAlgorithmImpl dsa = new DynamicStoreAlgorithmImpl();
dsa.init(1024);
String operation=null;
System.out.println("'add'添加进程 'delete'删除进程 'view'查看内存当前状态 'end'结束程序");
do{
operation = input.next();
if("add".equals(operation)){
System.out.println("请输入要添加的进程名和所需的内存大小。");
Process process = new Process();
String name = input.next();
int size = input.nextInt();
process.setpName(name);
process.setpSize(size);
dsa.allocatePartition(process);
System.out.println("进程正在运行...");
}else if("delete".equals(operation)){
System.out.println("请输入要删除的进程名。");
Process process = new Process();
String name = input.next();
process.setpName(name);
if(dsa.recoverPartition(process)){
System.out.println("进程已撤销...");
}else{
System.out.println("进程不存在...");
}
}else if("view".equals(operation)){
System.out.println("当前的内存状态");
dsa.show();
}
}while(!("end").equals(operation));
}
}