基于顺序搜索的动态分区分配算法模拟内存动态分配--最佳适应算法(best fit,BF)

18 篇文章 7 订阅
8 篇文章 0 订阅

BF算法、男朋友算法,哈哈
要实现动态分区分配,需要考虑三个方面的问题。分别是数据结构、分区分配算法、分区的分配与回收操作。

首数据结构

这里我们使用的是空闲分区链,采用双向链表表示空闲分区。
具体实现如下:

typedef struct LNode{
    int order;                       //表示内存块的顺序
    int start;                       //表示内存的初始地址
    int end;                         //表示内存的结束地址
    int size;                        //表示内存块的大小
    int state;                       //表示内存块的状态,1表示被占用,0表示空闲
    int process;                     //存储占用该内存块的进程的序号
    struct LNode *next;              //指向下一个内存块
    struct LNode *pre;               //指向上一个内存块
}LNode;
分配算法

采用基于顺序搜索的动态分区分配算法中的最佳适应(best fit BF)算法。
每次为作业分配内存时,总是把能满足要求,又是最小的空闲分区分配给作业,避免“大材小用”。

内存的分配与回收
  • 分配内存
    从空闲分区链中找到所需大小的分区。设请求的分区大小为u.size,表中每个空闲分区的大小可表示为m.size,若m.size-u.size>=0时进行内存分配操作,若大于0,则申请一新节点,插入到双向链表中,若等于0,则只需修改符合要求的结点的信息就行了。
  • 回收内存,四种情况(F:要回收的内存区、F1:F的前一分区、F2:F的后一分区)
    • F与F1地址衔接,且F1空闲,将F与F1合并,合并后结点首地址为F1首地址,末地址为F末地址,结点数减一。
    • F与F2地址衔接,且F2空闲,将F与F2合并,合并后结点首地址为F首地址,末地址为F2末地址地址,结点数减一。
    • F与F1和F2的地址衔接,且F1,F2空闲,合并后结点首地址为F1首地址,末地址为F2末地址,结点数减二。
    • 其他情况,将结点的state标志和process标志均设置为0。
程序解释
int buf[N]={100,500,200,700,300};   //内存块大小,用来初始化空闲分区链表
int add[N]={20,150,700,950,1700,};  //内存块的初始地址,用来初始化空闲分区链表
int dis[N]={301,400,310,105,190};   //进程所需内存,下标记为进程编号

List list_init();               //用来初始化空闲分区链表的函数,返回空闲分区链表的头部
void print(List head);          //顺序输出链表的信息
List allot_memory(List head,ing i);//为编号为i的进程分配内存
List free_memory(List head,int i);//释放编号为i的进程所占用的内存

全部代码

#include<stdio.h> 
#include<stdlib.h>

#define N 5

int buf[N]={100,500,200,700,300};
int add[N]={20,150,700,950,1700,};
int dis[N]={301,400,310,105,190};
typedef struct LNode *List;

typedef struct LNode{
    int order;
    int start;
    int end;
    int size;
    int state; 
    int process;
    struct LNode *next;
    struct LNode *pre;
}LNode;

List list_init(){
    List head,p,m;
    int i;
    for(i=0;i<N;i++){
        m=(List)malloc(sizeof(struct LNode));
        if(!m){
            printf("error\n");
            exit(0);
        }
        m->order=i+1;
        m->start=add[i];
        m->end=m->start+buf[i]-1;
        m->size=buf[i];
        m->next=NULL;
        m->pre=NULL;
        m->state=0;
        p->process=0;
        if(i==0)
            head=p=m;
        else{
            p->next=m;
            m->pre=p;
            p=p->next;
        }
    }
    return head;
}

void print(List head){
    List p=head;
    while(p){
        printf("第%d块内存--->始地址:%-5d--->末地址:%-5d--->大小:%-5d--->状态:",p->order,p->start,p->end,p->size);
        if(p->state==1)
            printf("被%d号进程占用中!\n",p->process);
        else if(p->state==0){
            printf("空闲中!\n");
        } 
        p=p->next;
    }
    printf("\n");
}

List free_memory(List head,int i){
    List p,m,temp;
    p=head;
    while(p){
        if(p->process==i+1){
            temp=p;
            if(p->next){
                m=p->next;
                if(p->end+1==m->start){
                    if(!m->state){
                        p->size+=m->size;
                        p->end+=m->size;
                        p->next=m->next;
                        p->state=0;
                        p->process=0;
                        if(m->next){
                            m->next->pre=p;
                        }
                        p=m->next;
                        free(m);
                        while(p){
                            p->order--;
                            p=p->next;
                        }
                    }
                    else{
                        p->state=0;
                        p->process=0;
                    }
                }
                else{
                    p->state=0;
                    p->process=0;
                }
            }
            p=temp;
            if(p->pre){
                m=p->pre;
                if(p->start==m->end+1){
                    if(!m->state){
                        m->size+=p->size;
                        m->end+=p->size;
                        m->next=p->next;
                        if(p->next){
                            p->next->pre=m;
                        }
                        free(p);
                        p=m->next;
                        while(p){
                            p->order--;
                            p=p->next;
                        }
                    }
                    else{
                        p->state=0;
                        p->process=0;
                    }
                }
                else{
                    p->state=0;
                    p->process=0;
                }
            }
            return head;
        }
        p=p->next;
    }
}

List allot_memory(List head,int i){
    int memory_size=dis[i];
    List p=head;
    List m;
    int min=-1;
    int order=-1;

    while(p){
        if(p->process-1==i){
            printf("内存中已有%d号进程了\n",i+1);
            return head;
        }
        p=p->next;
    }

    p=head;

    while(p){
        if(p->size>=memory_size&&p->state==0){
            if(min<0){
                min=p->size-memory_size;
                order=p->order;
            }
            else{
                if(min>p->size-memory_size){
                    min=p->size-memory_size;
                    order=p->order;
                }
            }
        }
        p=p->next;
    }
    if(order==-1){
        printf("%d号进程分配内存失败!\n",i+1);
        return head;
    }
    else{
        p=head;
        while(p){
            if(p->order==order){
                if(p->size==memory_size){
                    p->state=1;
                    p->process=i+1;
                    return head;
                }
                else{
                    m=(List)malloc(sizeof(struct LNode));
                    m->order=p->order;
                    m->start=p->start;
                    m->end=m->start+memory_size-1;
                    m->size=memory_size;
                    m->state=1;
                    m->next=p;
                    m->process=i+1;

                    m->pre=p->pre;
                    p->pre->next=m;
                    p->pre=m;
                    p->start=m->end+1;
                    p->size-=memory_size;
                    while(p){
                        p->order++;
                        p=p->next;
                    }
                    return head;
                }
            }
            p=p->next;
        }
    }
}

int main(){
    List p,m;
    int choice1,choice2;
    int i;
    p=list_init();


    print(p);
    p=allot_memory(p,3);
    print(p);
    p=allot_memory(p,3);
    p=free_memory(p,3);
    print(p);
    p=allot_memory(p,0);
    print(p);
    p=allot_memory(p,4);
    print(p);
    p=free_memory(p,4);
    print(p);
    p=allot_memory(p,4);
    print(p);
    p=free_memory(p,0);
    print(p);
    p=free_memory(p,4);
    print(p);
    return 0;
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<项目介绍> 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到94.5分,放心下载使用! 该资源适合计算机相关专业(如人工智能、通信工程、自动化、软件工程等)的在校学生、老师或者企业员工下载,适合小白学习或者实际项目借鉴参考! 当然也可作为毕业设计、课程设计、课程作业、项目初期立项演示等。如果基础还行,可以在此代码基础之上做改动以实现更多功能。 基于动态分区算法内存分配模拟程序,包括首次适应算法最佳适应算法、最坏适应算法。 一、项目功能 1. 提供三种动态分区模拟算法:首次适应算法最佳适应算法,最坏适应算法。 2. 利用画布动态显示内存分区当前情况(灰色为空闲,红色为已分配)。 3. 显示空闲分区链及已分配内存块情况。 4. 内存初始容量自行设定,使用前请初始化内存。 5. 分配算法可以自由选择,在运行期间也可以更换算法(但空闲分区链并不会按算法显示)。 6. 用户可随时添加新进程,输入进程名和长度后程序按照当前的分配算法进行分配内存默认分配空闲内存块的高地址部分。 7. 当申请内存容量大于任意一块空闲内存的大小时,将实行紧凑算法,程序将从后向前搜索空闲分区并计数,当空闲空间块的总容量大于进程需求容量时,算法停止搜索,将搜索最后一个空闲分区块之前的所有已分配内存块向前移动,将几个空闲分区块合并并放在高地址部分,然后执行正常分配算法,将当前合并的空闲分区块按高地址部分分出。 8. 如果当前紧凑算法结束,合并后的空闲分区块仍无法满足申请内存的需求,则会提示”内存不足,无法分配。“ 9. 用户可随时将申请的内存块释放,输入进程名称并点击返还即可释放内存。 10. 当进程名称不存在时,系统将给出错误提示。 二、项目信息 1. 项目使用IDEA_2017.3.5完成。 2. 在本项目中,笔者为IDEA添加了JFormDesigner插件,制作与修改客户端各个页面时需要用到这个插件。插件的安装及破解请自行百度。 3. JDK版本为1.8_211。
### 回答1: 动态异构分区内存分配与去配算法的设计,是一种适用于动态、多变的内存分配需求的优秀算法。 该算法的设计基于两个主要思路:一是根据内存需求的大小动态划分内存分区;二是根据已经分配内存空间的大小和位置,动态调整内存分区的大小和位置,使得可以更加高效地利用内存资源。同时,该算法还结合了内存分配算法内存回收算法,可以有效地避免内存碎片的产生和内存泄漏的问题。 在使用动态异构分区内存分配与去配算法时,需要注意以下几点: 1. 需要根据实际需求合理地设置内存分区的大小和数量,以便能够更好地利用内存资源。 2. 在分配内存时,需要考虑内存分区的大小和位置,选择合适的分区进行分配,以避免内存碎片的产生。 3. 在回收内存时,需要及时地将已经释放的内存空间合并到一起,以便能够更好地利用内存资源。 综上所述,动态异构分区内存分配与去配算法是一种非常优秀的内存分配算法,可以有效地解决内存碎片和内存泄漏等问题。在使用时需要注意合理设置内存分区的大小和数量,选择合适的内存分区进行分配,以及及时回收内存空间。 ### 回答2: 动态异长分区内存分配是指不同大小的内存块在系统中被动态地分配给不同的进程或者程序。在这种内存分配方式中,可能会出现内存碎片的问题,导致系统出现效率低下的现象。为解决这一问题,设计了去配算法,其中最佳适应算法是一种常用的去配算法最佳适应算法的主要思想是根据当前进程的内存需求寻找整个内存空间中最小的符合条件的空闲空间。具体来说,最佳适应算法首先会将内存空间按照大小进行排序,然后在分配内存时从小到大依次搜索可用的内存块,直到找到一个最小的满足需求的内存块为止。因为最佳适应算法是选择最小的空闲块,所以它可以避免大块的内存空间被浪费或者被拆分成小块。 最佳适应算法的优点是可以避免大量的内存碎片问题。由于它会尽可能地选择最小的内存块来分配给进程,因此可以保证内存空间的利用率最大化。此外,最佳适应算法还可以减少内存分配的时间复杂度,因为它只需要从小到大地遍历一次内存空间即可找到符合条件的内存块,而不用像其他算法那样需要遍历整个内存空间,从而加快了内存分配的速度。 然而,最佳适应算法也存在一些缺点。因为它要对内存空间进行排序,所以它的排序时间是一定要考虑进去的,而且由于其选择最小的内存块,所以会有大块的内存空间无法分配,从而浪费掉部分内存空间。 综上所述,最佳适应算法可以有效地解决动态异长分区内存分配中的内存碎片问题,但仍需在实际应用中考虑到排序时间和内存空间的利用率,根据实际情况选择适合的内存分配算法。 ### 回答3: 动态异长分区内存分配与去配算法的设计-最佳适应算法,可以有效地提高内存利用率和系统性能。最佳适应算法是一种动态分配内存空间的算法,其主要思想是,在当前可用的内存块中选择最小的能够容纳所需空间的块进行分配,以避免出现空间浪费或内存不足的情况。 最佳适应算法的具体实现步骤如下: 1、初始化分区表,将整个内存空间分成若干个分区,包括已分配和未分配的分区。 2、当需要分配内存时,从分区表中查找一个最小的未分配分区,能够容纳所需空间的分区。 3、对于查找到的分区进行分配,可以使用动态分配算法分配内存空间进行管理和控制。 4、当需要回收内存时,对已分配内存空间进行空间释放。 5、检查已分配内存空间和未分配的分区,如果有多个未分配的空间可以合并,则进行空间合并操作。 最佳适应算法的优点是充分利用了内存空间,避免了空间浪费,同时也提高了系统的性能和实现效率。缺点是在内存分配和回收时需要进行较多的操作,效率较低,容易产生碎片。 总之,最佳适应算法是一种比较实用和有效的动态分配内存空间的算法,可以在一定程度上提高系统的性能和内存利用率。在实际应用中,需要结合具体的系统需求和资源状况,进行合理的算法设计和实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值