import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
/**
* 内存管理最先分配算法
*
* @author LY
*
*/
public class caozuoxitong {
private static LinkedList<Job> spareList = new LinkedList<Job>();
private static LinkedList<Job> workList = new LinkedList();
private static LinkedList<Job> waitList = new LinkedList();//
/**
* 初始化固定内存空间
*/
public static void init(){
spareList.add(new Job(0,1000,0));//0为可用
}
/**
* 每次进来一个job,看job.startAdd 是不是spareList里面中的前一个或者后一个或者在中间,若有,进行合并,没有,add进去,然后更新等待
* @param spareList
* @return
*/
public void hebingJob(Job sourcejob){
System.out.println();
System.out.println("#######一次释放内存开始#######");
//不能在此处将值设死,后面会变化
/*int startAdd = sourcejob.getStartAdd();
int endAdd = sourcejob.getSize()+startAdd;*/
sourcejob.setState(0);//将状态改变为空闲
workList.remove(sourcejob);
Job goaljob1 = null;
Job goaljob2 = null;
Iterator<Job> iterator = spareList.iterator();
for (Job sparejob : spareList) {
//源job左边临接着一个job
if((sparejob.getStartAdd()+sparejob.getSize()==sourcejob.getStartAdd())){
System.out.println("释放的sourceJob在空闲队列中找到一个末地址和它可以合并的spareJob:"+sparejob.toString()+",进行合并");
System.out.println("合并前,sourcejob是:"+sourcejob.toString());
sourcejob.setStartAdd(sparejob.getStartAdd());
sourcejob.setSize(sparejob.getSize()+sourcejob.getSize());
System.out.println("合并后的Job是:"+sourcejob.toString());
goaljob1=sparejob;
//spareList.remove(sparejob);//删除并清空
//不能这里remove,remove后spareList少了一个,foreach循环少了一层
continue;
}
//源job右边临接着一个job
if(sparejob.getStartAdd()==sourcejob.getSize()+sourcejob.getStartAdd()){
//到这一步可以直接退出,如果左边有,则已经;连接上,前提是spareList中必须严格按照初始地址从大到小排序
System.out.println("释放的sourceJob在空闲队列中找到一个首地址和它末地址可以合并的spareJob,进行合并");
sourcejob.setSize(sparejob.getSize()+sourcejob.getSize());
System.out.println("合并后的Job是:"+sourcejob.toString());
goaljob2=sparejob;
//return;
}
}
if(goaljob1!=null){
spareList.remove(goaljob1);//将被合并的sparejob从链表中移除
}
if(goaljob2!=null){
spareList.remove(goaljob2);//将被合并的sparejob从链表中移除
}
System.out.println("释放的sourceJob经过处理,开始加入spareList");
//将sourcejob加入到Linkedlist中
spareList.add(sourcejob);
//排序
spareList = sortLinkedList(spareList);
System.out.println("___此时空闲队列情况如下___");
printspareQueue();
System.out.println("___此时运行队列情况如下___");
printWorkqueue();
System.out.println("#######一次释放内存完毕#######");
}
/**
* 在spareList先找到size等于或者大于该job1要求的大小的job,开始切割,切割完把被切割的job起始地址改变,长度去掉相应长度,将切割需要的job放入workList
* @param job
* @param size
* @return
*/
public void fenpeiJob(Job zuoye){
System.out.println("======一次内存分配开始=====");
List<Job> list = new LinkedList();
for(int i=0;i<spareList.size();i++){
if(zuoye.getSize()<=spareList.get(i).getSize()){
list.add(spareList.get(i));
}
}
Job goalJob = sortLinkedList(list).getFirst();
if(goalJob.getSize()==zuoye.getSize()){
goalJob.setState(1);
System.out.println("找到size="+goalJob.getSize()+"的空闲区"+"将"+goalJob.toString()+"从空闲队列移除");
spareList.remove(goalJob);
workList.add(goalJob);//进入运行队列
}else if(goalJob.getSize()>zuoye.getSize()){
spareList.remove(goalJob);
System.out.println("找到size="+goalJob.getSize()+"的空闲区"+",申请的size要求是"+zuoye.getSize()+"所以进行切割");
Job restJob = new Job(goalJob.getStartAdd()+zuoye.getSize(),goalJob.getSize()-zuoye.getSize(),0);
System.out.println("将切割后余下的空间返回给空闲队列:"+restJob.toString());
spareList.add(restJob);//切割剩下的内存空间返回给空闲队列
goalJob.setSize(zuoye.getSize());
goalJob.setState(1);
System.out.println("将切割后可以给作业运行的空间:"+goalJob.toString()+"取出来,放入运行队列");
workList.add(goalJob);//进入运行队列
}else{
System.out.println("内存不适合该作业运行,进入等待状态");
waitList.add(zuoye);
}
//最后进行排序
spareList = sortLinkedList(spareList);
System.out.println("___此时空闲队列情况如下___");
printspareQueue();
System.out.println("___此时运行队列情况如下___");
printWorkqueue();
System.out.println("======一次内存分配完毕=====");
System.out.println();
}
public LinkedList<Job> sortLinkedList(List<Job> sortList){
Job job1=null,job2=null;
boolean state = true;
for(int i=0;i<sortList.size() && state;i++){
state=false; //只要state在下一次外循环条件检测的时候值为false,就说明已经排好序,不用继续循环
for(int j=sortList.size()-1;j>i;j--){
job2 = sortList.get(j);
job1 = sortList.get(j-1);
if(job1.getStartAdd()>job2.getStartAdd()){
sortList.set(j-1, job2);
sortList.set(j, job1);
state=true;
}
}
}
return (LinkedList<Job>) sortList;
}
//输出运行队列
public void printWorkqueue(){
for (Job job : workList) {
System.out.println(job.toString());
}
}
public void printspareQueue(){
for (Job job : spareList) {
System.out.println(job.toString());
}
}
@Test
public void test(){
Job job = new Job(2);
Job job1 = new Job(2);
Job job2 = new Job(4);
Job job3 = new Job(6);
Job job4 = new Job(10);
Job job5 = new Job(13);
/* spareList.add(job1);
spareList.add(job5);
spareList.add(job3);
spareList.add(job4);
spareList.add(job);
spareList.add(job2);
sortLinkedList(spareList);*/
init();
System.out.println("增加作业,需要的空间为2");
fenpeiJob(job);
System.out.println("增加作业,需要的空间为2");
fenpeiJob(job1);
System.out.println("增加作业,需要的空间为4");
fenpeiJob(job5);
System.out.println("增加作业,需要的空间为6");
fenpeiJob(job3);
System.out.println("释放运行作业,首地址为4");
Job job6 = workList.get(2);
hebingJob(job6);
System.out.println("增加作业,需要的空间为13");
fenpeiJob(job4);
Job job7 = workList.get(2);
System.out.println("释放运行作业,首地址为17");
hebingJob(job7);
}
}
运行结果:
增加作业,需要的空间为2
======一次内存分配开始=====
找到size=1000的空闲区,申请的size要求是2所以进行切割
将切割后余下的空间返回给空闲队列:Job [startAdd=2, size=998, state=0]
将切割后可以给作业运行的空间:Job [startAdd=0, size=2, state=1]取出来,放入运行队列
___此时空闲队列情况如下___
Job [startAdd=2, size=998, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
======一次内存分配完毕=====
增加作业,需要的空间为2
======一次内存分配开始=====
找到size=998的空闲区,申请的size要求是2所以进行切割
将切割后余下的空间返回给空闲队列:Job [startAdd=4, size=996, state=0]
将切割后可以给作业运行的空间:Job [startAdd=2, size=2, state=1]取出来,放入运行队列
___此时空闲队列情况如下___
Job [startAdd=4, size=996, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
======一次内存分配完毕=====
增加作业,需要的空间为4
======一次内存分配开始=====
找到size=996的空闲区,申请的size要求是13所以进行切割
将切割后余下的空间返回给空闲队列:Job [startAdd=17, size=983, state=0]
将切割后可以给作业运行的空间:Job [startAdd=4, size=13, state=1]取出来,放入运行队列
___此时空闲队列情况如下___
Job [startAdd=17, size=983, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
Job [startAdd=4, size=13, state=1]
======一次内存分配完毕=====
增加作业,需要的空间为6
======一次内存分配开始=====
找到size=983的空闲区,申请的size要求是6所以进行切割
将切割后余下的空间返回给空闲队列:Job [startAdd=23, size=977, state=0]
将切割后可以给作业运行的空间:Job [startAdd=17, size=6, state=1]取出来,放入运行队列
___此时空闲队列情况如下___
Job [startAdd=23, size=977, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
Job [startAdd=4, size=13, state=1]
Job [startAdd=17, size=6, state=1]
======一次内存分配完毕=====
释放运行作业,首地址为4
#######一次释放内存开始#######
释放的sourceJob经过处理,开始加入spareList
___此时空闲队列情况如下___
Job [startAdd=4, size=13, state=0]
Job [startAdd=23, size=977, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
Job [startAdd=17, size=6, state=1]
#######一次释放内存完毕#######
增加作业,需要的空间为13
======一次内存分配开始=====
找到size=13的空闲区,申请的size要求是10所以进行切割
将切割后余下的空间返回给空闲队列:Job [startAdd=14, size=3, state=0]
将切割后可以给作业运行的空间:Job [startAdd=4, size=10, state=1]取出来,放入运行队列
___此时空闲队列情况如下___
Job [startAdd=14, size=3, state=0]
Job [startAdd=23, size=977, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
Job [startAdd=17, size=6, state=1]
Job [startAdd=4, size=10, state=1]
======一次内存分配完毕=====
释放运行作业,首地址为17
#######一次释放内存开始#######
释放的sourceJob在空闲队列中找到一个末地址和它可以合并的spareJob:Job [startAdd=14, size=3, state=0],进行合并
合并前,sourcejob是:Job [startAdd=17, size=6, state=0]
合并后的Job是:Job [startAdd=14, size=9, state=0]
释放的sourceJob在空闲队列中找到一个首地址和它末地址可以合并的spareJob,进行合并
合并后的Job是:Job [startAdd=14, size=986, state=0]
释放的sourceJob经过处理,开始加入spareList
___此时空闲队列情况如下___
Job [startAdd=14, size=986, state=0]
___此时运行队列情况如下___
Job [startAdd=0, size=2, state=1]
Job [startAdd=2, size=2, state=1]
Job [startAdd=4, size=10, state=1]
#######一次释放内存完毕#######