【JAVA操作系统——可变式分区分配】最佳适应算法

测试用例

可变式分区分配系统:内存初始空间为640KB,起始地址从0开始编址,采用最佳适应分区分配算法,对于以下进程请求,显示每次分配或回收后的内存空间情况。
  1. 进程1 申请100K
  2. 进程2 申请150K
  3. 进程3 申请300K
  4. 进程2 释放 150K
  5. 进程4 申请 80K
  6. 进程1 释放100K

代码实现

package com.zjh.dynamicPartition;

import java.util.LinkedList;
import java.util.Scanner;

/**
 * @author answer
 * @description: 最佳适应算法 找到满足要求且最小的分区
 * @since 2022-05-20 14:07
 */
public class BestFit {
    static Scanner scanner = new Scanner(System.in);
    /**
     * 内存分区
     */
    static class Zone{
        /** 大小 **/
        private int size;
        /** 初始地址 **/
        private int head;
        /** 当前状态 **/
        private String state;
        /** 作业号 **/
        private int num; //-1表示空闲

        public Zone(int size, int head, int num) {
            this.size = size;
            this.head = head;
            this.state = "空闲";
            this.num = num;
        }
    }
    /** 内存总大小 **/
    public static int memorySize;
    /** 空闲分区表 **/
    public static LinkedList<Zone> freeZones;

    /**
     * 初始化内存
     *
     * @param memorySize 内存大小
     */
    public BestFit(int memorySize){
        this.memorySize = memorySize;
        this.freeZones = new LinkedList<>();
        //向分区表加入空闲分区
        freeZones.add(new Zone(memorySize,0,-1));
    }


    /**
     * 寻找空闲分区 找到满足要求且最小的分区
     *
     * @param size 大小
     * @param num  作业号
     */
    public void findBestFree(int size,int num) {
        //标记最佳
        int bestSize = Integer.MAX_VALUE;
        //最佳分区的下标
        int bestIndex = 0;
        //判断是否找到
        boolean flag = false;
        for (int i = 0; i < freeZones.size(); i++) {
            if(freeZones.get(i).state.equals("空闲") && (freeZones.get(i).size > size)){
                //找到足够大的
                //判断是否更小
                if(freeZones.get(i).size < bestSize){
                    bestSize = freeZones.get(i).size;
                    bestIndex = i;
                    flag = true;
                }
            }
        }
        if (flag){
            allocation(size,bestIndex,freeZones.get(bestIndex),num);
        }else {
            //遍历完找不到没有空闲分区
            System.out.println("不存在可以存放"+size+"的内存分区");
        }
    }

    /**
     * 分配内存
     *
     * @param size     大小
     * @param index    下标
     * @param freeZone 空闲分区
     * @param num 作业号
     */
    public void allocation(int size, int index, Zone freeZone,int num){
        //创建新空闲分区
        Zone newZone = new Zone( freeZone.size - size,freeZone.head + size,-1);
        freeZones.add(index + 1,newZone);
        //将当前分区置为占用状态
        freeZone.size = size;
        freeZone.state = "占用";
        freeZone.num = num;
    }

    /**
     * 回收分区
     *
     * @param num 下标
     */
    public void recycle(int num){
        Zone zone = null;
        int index = -1;
        for (int i = 0; i < freeZones.size(); i++) {
            if(freeZones.get(i).num == num){
                zone = freeZones.get(i);
                index = i;
                break;
            }
        }
        //判断是否存在该分区
        if(zone == null){
            System.out.println("请输入正确的分区号!");
            return;
        }
        //判断分区是否被分配
        if(zone.state.equals("空闲")){
            System.out.println("此分区是空闲分区,无需回收");
            return;
        }
        //判断前后分区是否是空闲的,是则进行合并
        boolean front = false;
        boolean next = false;
        if(index - 1 >= 0){
            front = freeZones.get(index - 1).state.equals("空闲");
        }
        if(index + 1 <= freeZones.size() - 1){
            next = freeZones.get(index + 1).state.equals("空闲");
        }
        if(front && next){
            //前后都是空的,直接把三个都变成一个,下标变为前一个的
            Zone frontZone = freeZones.get(index - 1);
            Zone nextZone = freeZones.get(index + 1);
            frontZone.size = frontZone.size + zone.size + nextZone.size;
            frontZone.num = -1;
            //移除后两个
            freeZones.remove(index);
            freeZones.remove(index + 1);
        }else if(front && !next){
            //前一个是空的,后一个不是
            Zone frontZone = freeZones.get(index - 1);
            frontZone.size = frontZone.size + zone.size;
            //移除
            freeZones.remove(index);
            zone.state = "空闲";
            zone.num = -1;
        }else if(!front && next){
            //后一个是空的,前一个不是
            Zone nextZone = freeZones.get(index + 1);
            zone.size = zone.size + nextZone.size;
            //移除后一个
            freeZones.remove(index + 1);
            zone.state = "空闲";
            zone.num = -1;
        }else {
            //前后都非空,改变该分区状态
            zone.state = "空闲";
            zone.num = -1;
        }
        System.out.println("成功回收"+zone.size+"大小的空间");
    }

    /**
     * 打印当前分区表
     */
    private void printCurrent() {
        System.out.println("分区编号\t分区始址\t分区大小\t空闲状态\t作业号");
        for (int i = 0; i < freeZones.size(); i++){
            Zone zone = freeZones.get(i);
            System.out.println(i + "\t\t" + zone.head + "\t\t" +
                    zone.size + "  \t" + zone.state+ "  \t" + (zone.num == -1 ? "": zone.num));
        }
    }

    public static void main(String[] args) {
        System.out.println("=========最佳适应算法============");
        System.out.println("请输入初始内存总大小");
        int memorySize = scanner.nextInt();
        //初始化
        BestFit bestFit = new BestFit(memorySize);
        while(true) {
            System.out.println("请输入要分配内存还是要释放内存");
            System.out.println("1 分配内存 2 释放内存");
            int choice =scanner.nextInt();
            switch(choice) {
                case 1:{
                    System.out.println("请输入分配内存的作业号:");
                    int num = scanner.nextInt();
                    System.out.println("请输入要分配的内存大小");
                    int size = scanner.nextInt();
                    bestFit.findBestFree(size,num);
                    bestFit.printCurrent();
                    break;
                }
                case 2:{
                    System.out.println("输入想要释放内存的作业号");
                    int num = scanner.nextInt();
                    bestFit.recycle(num);
                    bestFit.printCurrent();
                    break;
                }
            }
        }
    }

}

测试结果截图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
可变分区分配是一种存储管理技术,用于为进程分配内存空间。它的主要特点是分区大小不固定,可以根据进程的需要进行动态调整。在这种技术中,物理内存被划分为多个可变大小的分区,每个分区可以分配给一个进程使用。 下面是实验四的步骤: 1. 设计数据结构:设计数据结构来存储可用分区和已分配分区的信息,包括分区的起始地址、大小和状态等。 2. 初始化分区:将整个物理内存划分为一个或多个可用分区,并将其添加到可用分区列表中。 3. 进程申请内存:当进程需要内存时,它向操作系统发出请求。操作系统会在可用分区列表中查找一个大小足够的分区来满足进程的需要。 4. 分配分区:如果找到了一个合适的分区操作系统会将该分区标记为已分配,并从可用分区列表中删除该分区,然后将该分区的起始地址返回给进程。 5. 释放分区:当进程不再需要某个分区时,它将释放该分区操作系统将该分区标记为可用,并将其添加到可用分区列表中。 6. 内存回收:当所有进程都结束时,操作系统将所有已分配分区标记为可用,以便下一批进程使用。 7. 碎片整理:在分配和释放分区的过程中,可能会出现内存碎片。为了最大化可用内存空间,可以实现碎片整理算法,将多个相邻的可用分区合并成一个更大的分区。 这些步骤可以通过编程实现。在实现过程中,需要注意保证数据结构的完整性和正确性,以及在内存分配和释放过程中避免死锁等问题的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jiong-952

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值