package Memory;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class OS {
ArrayList freeList=new ArrayList();//空闲区链表
ArrayList useList=new ArrayList();//使用区链表
Iterator freeIter,freeIter2,useIter;//使用迭代器对链表进行迭代
public OS(){//分配各分区大小
freeList.add(200d);
freeList.add(1000d);
freeList.add(1000d);
freeList.add(2048d);
freeList.add(512d);
}
public void print(){//打印当前的分区与内存信息
freeIter=freeList.iterator();//重新获取迭代器
double e=0; //用于统计总的内存大小
int j=0; //用于标记第j块分区
System.out.println("以下是剩余分区内存信息:");
while(freeIter.hasNext()){
double d=Double.parseDouble(freeIter.next().toString());
e=e+d;//统计总的内存大小
System.out.println("分区"+(j+1)+"还剩"+d+"kb大小");
j++;
}
System.out.println("总共剩下:"+e+"kb的内存大小");
useIter=useList.iterator();//迭代使用区链表
if(useIter.hasNext()==false)//如果没有正在使用的内存块
System.out.println("没有正在使用的内存块!\n");
else{
System.out.println("以下是已使用的内存块信息:");
e=0;//初始化e,用于统计总的使用区内存大小
j=1;//初始化j,用户标记第j块使用区
while(useIter.hasNext()){
double g=Double.parseDouble(useIter.next().toString());
e=e+g;
System.out.println("已使用第"+j+"块内存块的内存大小为:"+g+"kb");
j++;
}
System.out.println("总共使用了"+e+"kb大小的内存空间\n");
}
}
//最先适应分配算法
public void use1(double a){
//获取空闲区链表的迭代器
freeIter=freeList.iterator();
int i=0;//计数变量
while(freeIter.hasNext()){
double b=Double.parseDouble(freeIter.next().toString());
//从Object类型转化为double类型
//如果分区大于所需内存
if(b>=a){
freeList.remove(i);//移出链表
double c=b-a;//获得剩余内存大小,若不为空则插回链表中
if(c>0)
freeList.add(i,c);//插入原先元素的链表索引位置
useList.add(a);//添加到使用区链表中
System.out.println("*************使用最先适应分配算法:第"+(i+1)+"块分区成功分配内存"+a+"kb*************");
print();
break;
}
else
i++;//如果分区小于所需大小,循环
if(i==5){
System.out.println("*************没有足够大的分区!*************");
break;}
}
}
public void use2(double a){//最优分配算法
freeIter=freeList.iterator();//迭代空闲区
double c=-1;//用于判断分区大小与需要的内存之差
int i=-1;//用于标记最优的分区是第几块分区
int j=1;//用于标记当前分区
while(freeIter.hasNext()){ //空闲区指针所指向的对象不为空时
double
b=Double.parseDouble(freeIter.next().toString());//获取该分区大小
if((c==-1)&&(b-a)>=0){//如果还没找到合适的分区,且当前分区大于所需的内存
c=b-a;//内存之差赋值为当前分区减去所需分区
i=j;//标记当前分区
}
double d=b-a;//所剩分区大小:分区大小减去所需内存
if((d>=0)&&(d
c=d;//内存之差赋值为当前分区减去所需分区
i=j;//标记当前分区
}
if(c==0){//如果当前分区与所需的内存刚好相等,则使用当前分区,不再循环
i=j;//标记当前的分区
break;//如果分区大小与所需内存一样大,则选用此分区
}
j++;//没找到则继续循环
}
if(c<0)
System.out.println("*************没有足够大的分区!*************");
else{
freeList.remove(i-1);//移出索引标志的位置
if(c>0)//如果有剩余空间,则插回原来的位置上去
freeList.add(i-1,c);
useList.add(a);//插入使用区队列
System.out.println("*************使用最优适应分配算法:第"+i+"块分区成功分配内存"+a+"kb*************");
print();
}
}
public void use3(double a){//最坏适应分配算法
freeIter=freeList.iterator();//迭代空闲区
double c=-1;//用于判断分区大小与需要的内存之差
int i=-1;//用于标记最优的分区是第几块分区
int j=1;//用于标记当前分区
while(freeIter.hasNext()){ //空闲区指针所指向的对象不为空时
double
b=Double.parseDouble(freeIter.next().toString());//获取该分区大小
if((c==-1)&&(b-a)>=0){//如果还没找到合适的分区,且当前分区大于所需的内存
c=b-a;//内存之差赋值为当前分区减去所需分区
i=j;//标记当前分区
}
double d=b-a;//所剩分区大小:分区大小减去所需内存
if((d>=0)&&(d>c)){
//如果此分区比所需内存大且比之前的分区大,则替换为此分区,并标记索引位置
c=d;//内存之差赋值为当前分区减去所需分区
i=j;//标记当前分区
}
j++;//没找到则继续循环
}
if(c<0)
System.out.println("*************没有足够大的分区!*************");
else{
freeList.remove(i-1);//移出索引标志的位置
if(c>0)//如果有剩余空间,则插回原来的位置上去
freeList.add(i-1,c);
useList.add(a);//插入使用区队列
System.out.println("*************使用最坏适应分配算法:第"+i+"块分区成功分配内存"+a+"kb*************");
print();
}
}
public void callback(int a){//回收内存,参数为第a个内存块
double b=useList.remove(a-1);//索引位置为当前块块数减1
freeList.add(b);//内存返回到空闲区,插入到队尾
System.out.println("成功回收第"+a+"块内存");
print();
}
public void merge(int a,int b){//合并分区,传入参数为第a,b个分区
double c;
double d=0;
//判断ab大小,如果先删除索引位置小的,后面大的索引将删除不正确
if(a>b){
c=freeList.remove(a-1);//索引位置为当前分区减一
d=freeList.remove(b-1);
d=d+c;//合并分区大小
}
else{
c=freeList.remove(b-1);//索引位置为当前分区减一
d=freeList.remove(a-1);
d=d+c;//合并分区大小
}
freeList.add(d);//重新设置分区
System.out.println("成功合并第"+a+"和第"+b+"块分区");
print();
}
public void run(OS os){//控制台打印画面
while(true){
System.out.println("***********************请输入你要进行的操作***********************");
System.out.println("1.打印当前分区与内存情况\n"
+ "2.使用最先分配适应算法分配内存块\n"
+ "3.使用最优分配适应算法分配内存块 \n"
+ "4.使用最坏分配适应算法分配内存块 \n"
+ "5.回收内存块 \n"
+ "6.合并分区 \n"
+ "7.退出程序\n");
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
switch(a){
case 1:
os.print();
break;
case 2:
System.out.println("请输入你要分配的KB数:");
double b1=sc.nextDouble();
os.use1(b1);
break;
case 3:
System.out.println("请输入你要分配的KB数:");
double b2=sc.nextDouble();
os.use2(b2);
break;
case 4:
System.out.println("请输入你要分配的KB数:");
double b3=sc.nextDouble();
os.use3(b3);
break;
case 5:
System.out.println("请输入你要回收的块号:");
int c=sc.nextInt();
callback(c);
break;
case 6:
System.out.println("请输入你要回收的两个分区号");
int c2=sc.nextInt();
int c3=sc.nextInt();
os.merge(c2,c3);
break;
case 7:
System.out.println("退出程序");
System.exit(0);
default:
System.out.println("你的输入有误请重新输入!");
}
}
}
public static void main(String[] args) {
OS os=new OS();
os.run(os);
}
}