操作系统第5次实验报告:内存管理

姓名:那宝龙

学号:201821121054

班级:计算1812

1. 记录内存空间使用情况

typedef struct allocated_block{
    int p;
    int s;
    int t;
    char process_name[NAME];
    struct allocated_block *next;
}JL;

首先需要创建一个结构体,这结构体的目的时用来对各个进程的被分配到内存进行描述,其中各自含义包括了:p是进程id,s是进程,t是开始地址,pro_name[]是进程名数组,next则是next指针。

2. 记录空闲分区 

typedef struct free_block_type{
    int s;
    int t;
    struct free_block_type *next;
}FBT;

再弄一个空闲链表,用来对内存空闲分区进行描述,具体描述包括:s是大小,t是起始地址,next就是next指针,定义链表的头指针,内存空间初始化一下,内存分区就成了空闲分区了。

3.内存分配算法

int allocate_mem(JL *ab){
    /*分配内存模块*/
    FBT *fbt,*pre;
    int request_s=ab->s;
    fbt = pre = free_block;
    //尝试寻找可分配空闲,具体结果在函数中有解释
    int f = find_free_mem(request_s);
    if(f == -1){
        //不够分配
        printf("空闲内存不足,内存分配失败!\n");
        return -1;
    }else{
        if(f == 0){
            //需要内存紧缩才能分配
            memory_compact();
        }
        //执行分配
        do_allocate_mem(ab);
    }
    //重新排布空闲分区
    rearrange(ma_algorithm);
    return 1;
} 

//执行分配内存
void do_allocate_mem(JL *ab){
    int request = ab->s;
    FBT *tmp = free_block;
    while(tmp != NULL){
        if(tmp->s >= request){
            //分配
            ab->start_addr = tmp->start_addr;
            int shengyu = tmp->s - request;
            tmp->s = shengyu;
            tmp->start_addr = tmp->start_addr + request;
            
            return ;
        }
        tmp = tmp->next;
    }
}

void rearrange_FF(){
    /*首次适应算法,空闲区大小按起始地址升序排序*/
    //这里使用冒泡排序方法
    if(free_block == NULL || free_block->next == NULL)
        return;
    FBT *t1,*t2,*head;
    head = free_block;
    for(t1 = head->next;t1;t1 = t1->next){
        for(t2 = head;t2 != t1;t2=t2->next){
            if(t2->start_addr > t2->next->start_addr){
                int tmp = t2->start_addr;
                t2->start_addr = t2->next->start_addr;
                t2->next->start_addr = tmp;

                tmp = t2->size;
                t2->size = t2->next->size;
                t2->next->size = tmp;
            }
        }
    }
}

首次适配算法:百度上原话说的是从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区

4. 内存释放算法

首先释放链表结点,利用free()不断释放结点,更新分区表,进行可能的合并,将释放的结点放置在空闲分区的末结点,对空闲的链表进行排列,使用的是BF算法,若空闲区相邻,则做合并的操作,然后将空闲链表按照BF算法进行排序。

//释放链表节点
int dispose(JL *free_ab){
    /*释放ab数据结构节点*/
    JL *pre,*ab;
    if(free_ab == allocated_block_head){
        //如果要是释放第一个节点
        allocated_block_head = allocated_block_head->next;
        free(free_ab);
        return 1;
    }
    pre = allocated_block_head;
    ab = allocated_block_head->next;
    while(ab!=free_ab){
        pre = ab;
        ab = ab->next;
    }
    pre->next = ab->next;
    free(ab);
    return 2;
}

//更新分区表
int free_mem(JL *ab){
    /* 将ab所表示的已分配区归还,并进行可能的合并 */
    int algorithm = ma_algorithm;
    FBT *fbt,*pre,*work;
    fbt = (FBT*)malloc(sizeof(FBT));
    if(!fbt) return -1;
    /*
    进行可能的合并,基本策略如下?
    1. 将新释放的结点插入到空闲分区队列末尾?
    2. 对空闲链表按照地址有序排列?
    3. 检查并合并相邻的空闲分区?
    4. 将空闲链表重新按照当前算法排序
    */
    fbt->size = ab->size;
    fbt->start_addr = ab->start_addr;

    //插至末尾
    work = free_block;
    if(work == NULL){
        free_block = fbt;
        fbt->next == NULL;
    }else{
        while(work ->next != NULL){
            work = work->next;
        }
        fbt->next = work->next;
        work->next = fbt;
    }
    //按地址重新排布
    rearrange_FF();

    //合并可能分区;即若两空闲分区相连则合并
    pre = free_block;
    while(pre->next){
        work = pre->next;
        if(pre->start_addr + pre->size == work->start_addr ){
            pre->size = pre->size + work->size;
            pre->next = work->next;
            free(work);
            continue;
        }else{
            pre = pre->next;
        }
    }

    //按照当前算法排序
    rearrange(ma_algorithm);
    return 1;
}

int kill_process(int pid){
    AB *ab;
    ab = find_process(pid);
    if(ab!=NULL){
        free_mem(ab);    //释放ab所表示的分配表
        dispose(ab);    //释放ab数据结构节点
        return 0;
    }else{
        return -1;
    }
}

 

 

5. 运行结果

 

 

 

 

 

 

 

 

 

解释结果:

1)首先进程process-02分配了从0开始,大小为87的一块内存单元,分配后空闲分区内存剩余地址从87开始,大小为937的一块区域。
2)进程process-03分配了从87开始,大小为105的一块内存单元,分配后空闲分区内存剩余地址从192开始,大小为832的一块区域。
3)进程process-01分配了从192开始大小为102的一块内存单元,分配后空闲分区内存剩余地址从294开始,大小为730的一块区域。
4)进程process-02的内存空间,释放后空闲分区内存剩余地址从87开始大小为105的一块区域和地址从294开始大小为730的一块区域。

 

posted @ 2020-05-17 10:04  baolong22  阅读(247)  评论(0编辑  收藏  举报