zoukankan      html  css  js  c++  java
  • 操作系统第5次实验报告:内存管理

    • 姓名:吕煜华
    • 学号:201821121046
    • 班级:计算1812

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

    定义一个结构体AB来记录pid,大小,起始地址,进程名,定义一个指针allocated_block_head来指向链表的头结点

    /*每个进程分配到的内存块描述*/
    typedef struct allocated_block{
        int pid;
        int size;
        int start_addr;
        char process_name[NAME_LEN];
        struct allocated_block *next;
    }AB;
    
    /*进程分配内存块链表的首指针*/
    AB *allocated_block_head = NULL;

    2. 记录空闲分区

    定义空闲分区的结构体free_block_type,定义一个指针free block指向链表表头

    /*描述每一个空闲块的数据结构*/
    typedef struct free_block_type{
        int size;
        int start_addr;
        struct free_block_type *next;
    }FBT;
    
    /*指向内存中空闲块链表的首指针*/
    FBT *free_block;

    3. 内存分配算法

    为适应这种算法要使得空闲区的大小按起始地址升序排列。根据首次适配算法在空闲分区链表中搜索合适空闲分区进行分配,分配时如果找到可满足空闲分区且分配后剩余空间足够大,则分割;如果找不可满足需要的空闲分区但空闲分区之和能满足需要,则进行空闲分区的合并,然后再分配。在成功分配内存后,应保持空闲分区按照首次适配算法有序。

    int allocate_mem(AB *ab){
        
        FBT *fbt,*pre;
        int request_size=ab->size;
        fbt = pre = free_block;
        
        int f = find_free_mem(request_size);
        if(f == -1){
            //不够分配
            printf("空闲内存不足,内存分配失败!
    ");
            return -1;
        }else{
            if(f == 0){
               
                memory_compact();
            }
            //执行分配
            do_allocate_mem(ab);
        }
        //重新排布空闲分区
        rearrange(ma_algorithm);
        return 1;
    } 
    
    //执行分配内存
    void do_allocate_mem(AB *ab){
        int request = ab->size;
        FBT *tmp = free_block;
        while(tmp != NULL){
            if(tmp->size >= request){
                //分配
                ab->start_addr = tmp->start_addr;
                int shengyu = tmp->size - request;
                tmp->size = 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. 内存释放算法

    内存释放:找到对应的链表节点,释放释放杀死进程的内存块,归还进程的已分配的存储空间,按大小从小到大排序,释放链表节点。

    //释放链表节点
    int dispose(AB *free_ab){
     
        AB *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(AB *ab){
        int algorithm = ma_algorithm;
        FBT *fbt,*pre,*work;
        fbt = (FBT*)malloc(sizeof(FBT));
        if(!fbt) return -1;
    
        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);    
            dispose(ab);   
            return 0;
        }else{
            return -1;
        }
    }

    5. 运行结果

    (1)产生测试数据

     

    (2)解释结果:

    初始化的空闲分区的内存范围为0到1024,

    第一次操作为进程process-01分配了从0开始,大小为51的一块内存单元,分配后空闲分区内存剩余地址从51开始,大小为973的一块区域。

    第二次操作为进程process-02分配了从51开始,大小为54的一块内存单元,分配后空闲分区内存剩余地址从105开始,大小为919的一块区域。

    第三次操作为进程process-03分配了从105开始大小为11的一块内存单元,分配后空闲分区内存剩余地址从116开始,大小为908的一块区域。

  • 相关阅读:
    生成操作 嵌入的资源
    用JavaScript操作CSS滤镜实现最近新闻旁边的“new”
    26个ASP.NET常用性能优化方法
    kafka集群搭建(windows环境下)
    AtCoder Beginner Contest 215 F Dist Max 2(二分、尺取)
    CodeForces 1487C Minimum Ties(建图、模拟)
    C#获取 URL参数
    编程给程序员带来哪些坏习惯
    【转载】IIS和服务器安全设置教程
    [转载]在IE8下动易SiteWeaver后台编辑器按钮没有反应的解决方案
  • 原文地址:https://www.cnblogs.com/lvyuhua/p/12905961.html
Copyright © 2011-2022 走看看