内存分区分配--首次适应算法(操作系统)

内存分区分配–首次适应算法

输入内存的大小和阈值minsize,按照首次适应算法进行连续的分区分配。在划分时,若剩余的内存小于等于minsize,则将整块内存分配给该进程不再进行划分。 根据菜单选择相应的操作:

1.初始化:输入内存的大小和阈值minsize,初始状态下空闲分区名字为“void”。

2.分配:输入申请进程的名字、大小。

  • 若可以分配,显示“分配成功!”;
  • 若剩余空间不足,显示不分配原因“剩余空间不足,不予分配。”;
  • 若剩余的空间通过紧凑技术,可以再分配,提示“是否通过紧凑技术,重新划分?(Y/N)”若选择“Y”,通过紧凑技术重新划分并分配,成功后,显示“分配成功!”若选择“N”,则输出“没有合适的剩余空间,不予分配。”

3.回收:输入回收进程的名字,若有相邻空闲分区,需要合并,并输出“回收成功!”;若输入错误,提示“查无此分区!” 4.显示:显示当前内存的分配状态。

0.退出

其他:输出“输入错误,请重新输入。”

输入格式:

先进行初始化后,按照菜单进行相应的操作。

输出格式:

菜单只显示一次,按照相应的选择输出。

输入样例1:

在这里给出一组输入。例如:

1
1024 5
4
0

输出样例1:

在这里给出相应的输出。例如:

1.初始化
2.分配
3.回收
4.显示
0.退出
请选择:
分区号 分区 起始地址 结束地址 大小 当前状态
1 void 0 1023 1024 空闲

输入样例2:

在这里给出一组输入。例如:

1
1000 5
2
A 100
2
B 200
2
C 150
2
D 250
2
E 200
2
F 95
4
0

输出样例2:

在这里给出相应的输出。例如:

1.初始化
2.分配
3.回收
4.显示
0.退出
请选择:
分配成功!
分配成功!
分配成功!
分配成功!
分配成功!
分配成功!
分区号 分区 起始地址 结束地址 大小 当前状态
1 A 0 99 100 已分配
2 B 100 299 200 已分配
3 C 300 449 150 已分配
4 D 450 699 250 已分配
5 E 700 899 200 已分配
6 F 900 999 100 已分配

输入样例3:

在这里给出一组输入。例如:

1
1000 5
2
A 100
2
B 200
2
C 150
2
D 250
2
E 200
2
F 150
4
0

输出样例3:

在这里给出相应的输出。例如:

1.初始化
2.分配
3.回收
4.显示
0.退出
请选择:
分配成功!
分配成功!
分配成功!
分配成功!
分配成功!
剩余空间不足,不予分配。
分区号 分区 起始地址 结束地址 大小 当前状态
1 A 0 99 100 已分配
2 B 100 299 200 已分配
3 C 300 449 150 已分配
4 D 450 699 250 已分配
5 E 700 899 200 已分配
6 void 900 999 100 空闲

输入样例4:

在这里给出一组输入。例如:

1
1000 5
2
A 100
2
B 200
2
C 150
2
D 250
2
E 200
2
F 150
3
A
4
0

输出样例4:

在这里给出相应的输出。例如:

1.初始化
2.分配
3.回收
4.显示
0.退出
请选择:
分配成功!
分配成功!
分配成功!
分配成功!
分配成功!
剩余空间不足,不予分配。
回收成功!
分区号 分区 起始地址 结束地址 大小 当前状态
1 void 0 99 100 空闲
2 B 100 299 200 已分配
3 C 300 449 150 已分配
4 D 450 699 250 已分配
5 E 700 899 200 已分配
6 void 900 999 100 空闲

输入样例5:

在这里给出一组输入。例如:

1
1000 5
2
A 100
2
B 200
2
C 150
2
D 250
2
E 200
2
F 150
3
A
2
X 150
Y
4
0

输出样例5:

在这里给出相应的输出。例如:

1.初始化
2.分配
3.回收
4.显示
0.退出
请选择:
分配成功!
分配成功!
分配成功!
分配成功!
分配成功!
剩余空间不足,不予分配。
回收成功!
是否通过紧凑技术,重新划分?(Y/N)
分配成功!
分区号 分区 起始地址 结束地址 大小 当前状态
1 B 0 199 200 已分配
2 C 200 349 150 已分配
3 D 350 599 250 已分配
4 E 600 799 200 已分配
5 X 800 949 150 已分配
6 void 950 999 50 空闲
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int choice,merSize = 0,minSize = 0,merSizeStart = 0,resultNumber = 0;
        boolean flagTar;
        int requireSize = 0,flagNumber = -1;
        String proName,strTar;
        Scanner sc  = new Scanner(System.in);
        List<Part> parts = new ArrayList<>();
        System.out.println("1.初始化\n" + "2.分配\n" + "3.回收\n" + "4.显示\n" + "0.退出");
        System.out.println("请选择:");
        choice = sc.nextInt();

        while (choice!=0){
            switch (choice){

                //初始化=>输入内存的大小和阈值minsize,初始状态下空闲分区名字为“void”。
                case 1:
                    merSize = sc.nextInt();
                    minSize = sc.nextInt();
                    merSizeStart = merSize;
                    Part partStart = new Part(-3,"void",0,merSize-1,merSize,"空闲");
                    parts.add(partStart);
                    break;

                //分配=>输入申请进程的名字、大小
                case 2:
                    if("void".equals(parts.get(0).partName)&&parts.get(0).size == merSizeStart){
                        parts.remove(0);  //删除第一次的void分区
                    }

                    proName = sc.next();
                    requireSize = sc.nextInt();

                    flagTar = alloction(parts,merSize,minSize,proName,requireSize);

                    if (flagTar){
                        System.out.println("是否通过紧凑技术,重新划分?(Y/N)");
                        strTar = sc.next();
                        if (strTar.equals("N"))
                            System.out.println("没有合适的剩余空间,不予分配。");
                        else {
                            //直接进行紧凑分配
                            resultNumber = compact(parts,proName,requireSize,merSize,minSize);
                            System.out.println("分配成功!");
                        }
                    }
                    if(flagTar) merSize = resultNumber;
                    else if (merSize - requireSize <= minSize && merSize - requireSize >0) merSize = 0;
                    else if (merSize - requireSize >0&&resultNumber == 0)
                        merSize -=requireSize;
                    else if (resultNumber!=0)merSize  = resultNumber;
                    break;

                //回收=>输入回收进程的名字,若有相邻空闲分区,需要合并,并输出“回收成功!”;若输入错误,提示“查无此分区!”
                case 3:
                    int flag = -1;
                    proName = sc.next();
                    for (int i = 0; i < parts.size(); i++) {
                        if (proName.equals(parts.get(i).partName)) {
                            flag = i;
                            break;
                        }
                    }
                    if (flag != -1){
                        //进行内存回收
                        recovery(parts,flag);
                    } else
                        System.out.println("查无此分区!");
                    break;

                //显示=>显示当前内存的分配状态。
                case 4:
                    flagNumber = printList(parts,merSize,minSize,merSizeStart);
                    if (flagNumber != 0) merSize = flagNumber;
                    break;

                default:
                    System.out.println("输入错误,请重新输入。");
                    break;
            }
            choice = sc.nextInt();
        }

    }

    //分区类Part
    static class Part{
        int partNumber;
        String partName;
        int startAddr,endAddr;
        int size;
        String state;

        public Part() {
        }

        public Part(int partNumber, String partName, int startAddr, int endAddr, int size, String state) {
            this.partNumber = partNumber;
            this.partName = partName;
            this.startAddr = startAddr;
            this.endAddr = endAddr;
            this.size = size;
            this.state = state;
        }

        public int getPartNumber() {
            return partNumber;
        }

        public void setPartNumber(int partNumber) {
            this.partNumber = partNumber;
        }

        public String getPartName() {
            return partName;
        }

        public void setPartName(String partName) {
            this.partName = partName;
        }

        public int getStartAddr() {
            return startAddr;
        }

        public void setStartAddr(int startAddr) {
            this.startAddr = startAddr;
        }

        public int getEndAddr() {
            return endAddr;
        }

        public void setEndAddr(int endAddr) {
            this.endAddr = endAddr;
        }

        public int getSize() {
            return size;
        }

        public void setSize(int size) {
            this.size = size;
        }

        public String getState() {
            return state;
        }

        public void setState(String state) {
            this.state = state;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Part part = (Part) o;
            return partNumber == part.partNumber &&
                    startAddr == part.startAddr &&
                    endAddr == part.endAddr &&
                    size == part.size &&
                    Objects.equals(partName, part.partName) &&
                    Objects.equals(state, part.state);
        }

        @Override
        public int hashCode() {

            return Objects.hash(partNumber, partName, startAddr, endAddr, size, state);
        }
    }

    //分配函数
    public static boolean alloction(List<Part> parts,int merSize,int minSize,String proName,int requireSize){

        int restSpace = 0,tmp = 0,restSpace01 = 0;
        boolean flag = false,flagTmp = false,flag01 = false;

        for (int i = 0; i < parts.size(); i++) {
            if (parts.get(i).state.equals("空闲")&&parts.get(i).size >= requireSize){
                tmp = i;
                flagTmp = true;
                break;
            }
            if (parts.get(i).state.equals("空闲"))
                restSpace01+=parts.get(i).size;
        }

        if (flagTmp){
            if (parts.get(tmp).size - requireSize <= minSize){
                parts.add(tmp,new Part(1,proName,parts.get(parts.size()-1).endAddr+1,
                        parts.get(parts.size()-1).endAddr+parts.get(tmp).size,parts.get(tmp).size,"已分配"));
                parts.get(tmp+1).size = 0;
            } else{
                parts.add(tmp,new Part(1,proName,parts.get(parts.size()-1).endAddr+1,
                        parts.get(parts.size()-1).endAddr+requireSize,requireSize,"已分配"));
                parts.get(tmp+1).endAddr -= requireSize;
                parts.get(tmp+1).size -= requireSize;
            }
                    if (parts.get(tmp+1).size == 0)
                            parts.remove(tmp+1);
                    //更新数据
            for (int i = 0; i < parts.size(); i++) {
                if (i == 0){
                    parts.get(0).setStartAddr(0);
                    parts.get(0).setEndAddr(parts.get(0).size-1);
                }else {
                    parts.get(i).startAddr = parts.get(i-1).endAddr + 1;
                    parts.get(i).endAddr = parts.get(i-1).endAddr + parts.get(i).size ;
                }
            }
            System.out.println("分配成功!");
        }else if(restSpace01 >= requireSize){
            flag = true;
            flag01 = true;
        } else if(merSize >= requireSize&& flag01 == false){
            if (parts.size() == 0){
                if(merSize-requireSize<=minSize)
                    parts.add(new Part(1,proName,0,merSize-1,merSize,"已分配"));
                else
                    parts.add(new Part(1,proName,0,requireSize-1,requireSize,"已分配"));
            }
            else{
                int startAddr = parts.get(parts.size()-1).size + parts.get(parts.size()-1).startAddr;
                if (merSize-requireSize<=minSize){
                    parts.add(new Part(1,proName,startAddr,startAddr + merSize - 1,merSize,"已分配"));
                }else
                    parts.add(new Part(1,proName,startAddr,startAddr + requireSize - 1,requireSize,"已分配"));
            }
            System.out.println("分配成功!");
        }else {
            //循环遍历parts数组,找出“空闲”的被回收的内存区域,再加上没有被分配的内存区域,是否够紧凑分配的
            for (Part part : parts) {
                if("空闲".equals(part.state))
                    restSpace += part.size;
            }
            //空闲资源加上剩下没有被分配的空间是否大于需要的空间
            if (restSpace+merSize >= requireSize){
                flag = true;
            }else{
                System.out.println("剩余空间不足,不予分配。");
            }
        }
        return flag;
    }

    //紧凑分配
    public static int compact(List<Part> parts, String proName, int requireSize, int merSize,int minSize){
        int flag = 0,restSpace = 0;

        flag1:
        for (int i = 0; i < parts.size(); i++) {
            //可能会报错i+1数组越界,不过问题不大
            if (parts.get(i).state.equals("空闲") && i == 0 ){
                parts.get(i+1).startAddr = 0;
                parts.get(i+1).endAddr = parts.get(i+1).size-1;
                merSize += parts.get(i).size;
                if (merSize >= requireSize){
                    //partNumber赋值-1 一会儿作为标志删除对应的空闲区域
                    parts.get(0).partNumber = -1;
                    flag = 1;
                    i++;
                    continue flag1;
                }
            }else if (parts.get(i).state.equals("空闲")){
                //回收之后造成的碎片化
                parts.get(i+1).startAddr = parts.get(i).startAddr;
                parts.get(i+1).endAddr = parts.get(i).endAddr + parts.get(i+1).size ;
                merSize += parts.get(i).size;
                if (merSize >= requireSize){
                    parts.get(i).partNumber = -1;
                    flag =1;
                    i++;
                    continue flag1;
                }
            }
        }

        //对刚才标记partNumber为-1的进程进行删除
        for (int i = 0; i < parts.size(); i++) {
            if (parts.get(i).partNumber == -1|| parts.get(i).state.equals("空闲")) {
                //remove之后数组索引重新从0开始
                parts.remove(i);
                i--;
            }
        }

        //对各个内存进行更新
        for (int i = 0; i < parts.size(); i++) {
            if (i != 0){
                parts.get(i).startAddr = parts.get(i-1).endAddr + 1;
                parts.get(i).endAddr = parts.get(i).startAddr + parts.get(i).size -1;
            }
        }
        merSize -=requireSize;
        if(merSize <= minSize){
            parts.add(new Part(1,proName,parts.get(parts.size()-1).endAddr+1,
                    parts.get(parts.size()-1).endAddr+requireSize+merSize,requireSize+merSize,"已分配"));
            merSize = 0;
        }else
            //添加新的请求内存分区
            parts.add(new Part(1,proName,parts.get(parts.size()-1).endAddr+1,
                    parts.get(parts.size()-1).endAddr+requireSize,requireSize,"已分配"));

        return merSize;
    }

    //进行内存回收
    public static void recovery(List<Part> parts,int targetIndex){
        if(targetIndex == 0 && parts.size() == 1){
            parts.get(0).partName = "void";
            parts.get(0).state = "空闲";
        }else if (targetIndex == 0&&parts.get(targetIndex+1).state.equals("已分配")){
            parts.get(0).partName = "void";//开头结尾的判断
            parts.get(0).state = "空闲";
        }else if (targetIndex == 0&&parts.get(targetIndex+1).state.equals("空闲")){
            parts.get(targetIndex).partName = "void";
            parts.get(targetIndex).endAddr += parts.get(targetIndex+1).size;
            parts.get(targetIndex).size += parts.get(targetIndex+1).size;
            parts.remove(targetIndex+1);
        }
        else if (targetIndex == parts.size()-1&&parts.get(targetIndex-1).state.equals("已分配")){
            parts.get(targetIndex).partName = "void";
            parts.get(targetIndex).state = "空闲";
        }else if (targetIndex == parts.size()-1&&parts.get(targetIndex-1).state.equals("空闲")){
            parts.get(targetIndex-1).partName = "void";
            parts.get(targetIndex-1).endAddr += parts.get(targetIndex).size;
            parts.get(targetIndex-1).size += parts.get(targetIndex).size;
            parts.remove(targetIndex);
        }
        else if (parts.get(targetIndex-1).state.equals("空闲")&&parts.get(targetIndex+1).state.equals("已分配")){
            parts.get(targetIndex-1).partName = "void";
            parts.get(targetIndex-1).endAddr += parts.get(targetIndex).size;
            parts.get(targetIndex-1).size += parts.get(targetIndex).size;
            parts.remove(targetIndex);
        }else if (parts.get(targetIndex+1).state.equals("空闲")&&parts.get(targetIndex-1).state.equals("已分配")){
            parts.get(targetIndex).partName = "void";
            parts.get(targetIndex).endAddr += parts.get(targetIndex+1).size;
            parts.get(targetIndex).size += parts.get(targetIndex+1).size;
            parts.remove(targetIndex+1);
        }else if (parts.get(targetIndex-1).state.equals("空闲")&&parts.get(targetIndex+1).state.equals("空闲")){
            parts.get(targetIndex-1).partName = "void";
            parts.get(targetIndex-1).endAddr =  parts.get(targetIndex).size + parts.get(targetIndex+1).size + parts.get(targetIndex-1).endAddr;
            parts.get(targetIndex-1).size =  parts.get(targetIndex).size + parts.get(targetIndex+1).size + parts.get(targetIndex-1).size;
            parts.remove(targetIndex);
            parts.remove(targetIndex);
        }else {
            parts.get(targetIndex).partName = "void";
            parts.get(targetIndex).state = "空闲";
        }

        for (int i = 0; i < parts.size(); i++) {
            if (i != 0){
                parts.get(i).startAddr = parts.get(i-1).endAddr + 1;
                parts.get(i).endAddr = parts.get(i).startAddr + parts.get(i).size -1;
            }
        }
        System.out.println("回收成功!");
    }

    //打印函数
    public static int printList(List<Part> parts,int merSize,int minSize,int initMerSize){
        int flag = 0;
        for (Part part : parts) {
            initMerSize -= part.size;
        }
        merSize = initMerSize;
        //最后查看是否初始的内存资源分配完全
        if (merSize != 0&&parts.get(parts.size()-1).partNumber!=-3){
            if (parts.get(parts.size()-1).state.equals("空闲")){
                parts.get(parts.size()-1).endAddr += merSize;
                parts.get(parts.size()-1).size += merSize;
            }else
                parts.add(new Part(1,"void",parts.get(parts.size()-1).endAddr+1,
                        parts.get(parts.size()-1).endAddr+merSize,merSize,"空闲"));
        }

        int i = 1;
        System.out.println("分区号 分区 起始地址 结束地址 大小 当前状态");
        for (Part part : parts) {
            System.out.println(i++ +" "+part.partName+" "+part.startAddr+" "+part.endAddr+" "+part.size+" "+part.state);
        }
        if(parts.size() != 1&&parts.get(parts.size()-1).state.equals("空闲"))
            flag = parts.remove(parts.size()-1).size;
        if (parts.size() == 1&&parts.get(0).state.equals("空闲")) flag = parts.get(0).size;
        return  flag;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值