• 模拟linux的内存分配与回收


    模拟linux的内存分配与回收

    要求

    通过深入理解内存分配管理的三种算法,定义相应的数据结构,编写具体代码。 充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。
    (1)掌握内存分配FF,BF,WF策略及实现的思路;
    (2)掌握内存回收过程及实现思路;
    (3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行。

    主要过程

    实现

    #include<stdio.h>
    #include<stdlib.h>
    
    #define PROCESS_NAME_LEN 32
    #define MIN_SLICE 10
    #define DEFAULT_MEM_SIZE 1048
    #define DEFAULT_MEM_START 0
    #define MA_FF 1
    #define MA_BF 2
    #define MA_WF 3
    
    typedef struct free_block_struct{
        int size;
        int start_addr;
        struct free_block_struct *next;
    }free_block_type;
    free_block_type *free_block;
    
    typedef struct allocated_block_struct{
        int pid;
        int size;
        int start_addr;
        char process_name[PROCESS_NAME_LEN];
        struct allocated_block_struct *next;
    }allocated_block;
    allocated_block *allocated_block_head=NULL;
    
    int memory_size_setted=0;
    int mem_size=DEFAULT_MEM_SIZE;
    int pid=0;
    int memory_algorithm=1;
    
    free_block_type* init_free_block()
    {
        free_block_type* fb=(free_block_type*)malloc(sizeof(free_block_type));
    
        if(fb==NULL)  return NULL;
        fb->size=mem_size;
        fb->start_addr=DEFAULT_MEM_START;
        fb->next=NULL;
        return fb;
    }
    
    void display_menu()
    {
        printf("*****************************************************
    ");
        printf("1. set memory size(default=%d)
    ",DEFAULT_MEM_SIZE);
        printf("2. select memory allocation algorithm
    ");
        printf("3. new process
    ");
        printf("4. kill process
    ");
        printf("5. display memory usage
    ");
        printf("0. exit
    ");
        printf("*****************************************************
    ");
    }
    
    int set_mem_size()
    {
        int size;
        if(memory_size_setted)
        {
            printf("memory size has been setted.
    ");
            return 0;
        }
    
        printf("total memory size:");
        scanf("%d",&size);
        char c;while ((c = getchar()) != EOF && c != '
    ');
        if(size>0)
        {
            mem_size=size;
            free_block->size=mem_size;
            memory_size_setted=1;
            return 1;
        }
        else
            return 0;
    }
    
    void alg_sort1(int mode)//1 up,0 down
    {
        free_block_type *pre,*p,*np,*head;
        pre=(free_block_type*)malloc(sizeof(free_block_type));
        pre->next=free_block;// add head node
    
        p=free_block;
        int len=0;
        while(p)
        {
            len++;
            p=p->next;
        }
        p=free_block;
        for(int i=0;i<len;i++)
        {
            int first=1;
            for(int j=0;j<len-i-1;j++)
            {
                if(first==1)
                {
                    head=pre;
                    first=0;
                    np=p->next;
                }
                if(mode)//down
                {
                    if(p->size>np->size)
                    {
                        pre->next=np;
                        p->next=np->next;
                        np->next=p;
                    }
                }
                else
                {
                    if(p->size<np->size)
                    {
                        pre->next=np;
                        p->next=np->next;
                        np->next=p;
                    }
                }
                pre=p;
                p=np;
                np=np->next;
            }
            pre=head;
        }
        free_block=pre->next;
    }
    void swap(int *a,int *b)
    {
        int t=*a; *a=*b; *b=t;
    }
    void alg_sort(int mode)//1 up,0 down
    {
        free_block_type *p,*np;
    
        p=free_block;
        int len=0;
        while(p)
        {
            len++;
            p=p->next;
        }
        for(int i=0;i<len;i++)
        {
            p=free_block;
            for(int j=0;j<len-i-1;j++)
            {
                np=p->next;
                if(mode)//down
                {
                    if(p->size>np->size)
                    {
                        swap(&p->size,&np->size);
                        swap(&p->start_addr,&np->start_addr);
                    }
                }
                else
                {
                    if(p->size<np->size)
                    {
                        swap(&p->size,&np->size);
                        swap(&p->start_addr,&np->start_addr);
                    }
                }
                p=np;
            }
        }
    }
    void rearrange_FF()
    {
        return;
    }
    void rearrange_BF()
    {
        alg_sort(1);
    }
    void rearrange_WF()
    {
        alg_sort(0);
    }
    void rearrange(int n)
    {
        switch(n)
        {
            case MA_FF:rearrange_FF();break;
            case MA_BF:rearrange_BF();break;
            case MA_WF:rearrange_WF();break;
        }
    }
    void set_algorithm()
    {
        int algorithm;
        printf("1. first fit
    ");
        printf("2. best fit
    ");
        printf("3. worst fit
    ");
        scanf("%d",&algorithm);
        char c;while ((c = getchar()) != EOF && c != '
    ');
        if(algorithm>=1&&algorithm<=3)
        {
            rearrange(algorithm);
            memory_algorithm=algorithm;
        }
        else
            printf("choice out of range
    ");
    }
    
    int allocate_mem(allocated_block *ab)
    {
       int request=ab->size;
       free_block_type *p,*pre;
       pre=NULL;
       p=free_block;
    
       int first=1;
       while(p)
       {
            if(p->size>=request)
            {
                ab->start_addr=p->start_addr;
                int rest=p->size-request;
                if(rest<MIN_SLICE)
                {
                    ab->size+=rest;
                }
                else
                {
                    free_block_type *new_block=(free_block_type*)malloc(sizeof(free_block_type));
    
                    new_block->size=rest;
                    new_block->start_addr=p->start_addr+request;
                    new_block->next=p->next;
                    ab->next=NULL;
                    if(first)
                        free_block=new_block;
                    else
                        pre->next=new_block;
                }
                p->size-=ab->size;
                rearrange(memory_algorithm);
                // free(p);
                // free(pre);
                return 1;
            }
            first=0;
            pre=p;
            p=p->next;
       }
       return -1;
    }
    int new_process()
    {
        allocated_block *ab=(allocated_block*)malloc(sizeof(allocated_block));
        if(ab==NULL) return -1;
        ab->next=NULL;
        pid++;
        sprintf(ab->process_name,"process_%02d",pid);
        ab->pid=pid;
    
        printf("memory for %s:",ab->process_name);
        int size,ret;
        scanf("%d",&size);
        char c;while ((c = getchar()) != EOF && c != '
    ');
        if(size<=0) return 0;
        ab->size=size;
        ret=allocate_mem(ab);
    
        if(ret==1&&allocated_block_head==NULL)
        {
            allocated_block_head=ab;
            return 1;
        }
        else if(ret==1)
        {
            ab->next=allocated_block_head;
            allocated_block_head=ab;
            return 1;
        }
        else
        {
            printf("allocated failed
    ");
            free(ab);
            return -1;
        }
    }
    allocated_block* find_process(int pid)
    {
        allocated_block *p;
        p=allocated_block_head;
        while(p)
        {
            if(p->pid==pid) return p;
            p=p->next;
        }
        return NULL;
    }
    void free_mem(allocated_block *ab)
    {
        free_block_type *fbt=(free_block_type*)malloc(sizeof(free_block_type)),*p,*np;
        fbt->size=ab->size;
        fbt->start_addr=ab->start_addr;
        fbt->next=NULL;
    
        p=free_block;
        while(p->next)
            p=p->next;
        if(p->start_addr+p->size==fbt->start_addr)
            {
                p->size+=fbt->size;
                p->next=NULL;
            }
        else
            p->next=fbt;
    
        rearrange(2);
        p=free_block;
        while(p->next)
        {
            np=p->next;
            if(p->start_addr+p->size==np->start_addr)
                {
                    p->size=p->size+np->size;
                    p->next=np->next;
                }
            else
                p=np;
        }
        rearrange(memory_algorithm);
    }
    void dispose(allocated_block *ab)
    {
        if(ab==allocated_block_head)
        {
            allocated_block_head=allocated_block_head->next;
            free(ab);
            return;
        }
        allocated_block *pre,*p;
        pre=allocated_block_head;
        p=allocated_block_head->next;
        while(p!=ab)
        {
            pre=p;
            p=p->next;
        }
        pre->next=p->next;
        free(ab);
    }
    void kill_process()
    {
        allocated_block *ab;
        int pid;
        printf("kill process,pid:");
        scanf("%d",&pid);
        char c;while ((c = getchar()) != EOF && c != '
    ');
        ab=find_process(pid);
        if(ab!=NULL)
        {
            free_mem(ab);
            dispose(ab);
        }
        else
        {
            printf("wrong pid,try again
    ");
        }
    }
    
    void display_mem_usage()
    {
        free_block_type *fbt=free_block;
        allocated_block *ab=allocated_block_head;
        if(fbt==NULL) return;
        printf("
    ");
        printf("free memory:
    ");
        printf("%20s %20s
    ","start_addr","size");
        while(fbt!=NULL)
        {
            if(fbt->size)
                printf("%20d %20d
    ",fbt->start_addr,fbt->size);
            fbt=fbt->next;
        }
    
        printf("memory used:
    ");
        printf("%10s %20s %10s %10s
    ","pid","process_name","start_addr","size");
        while(ab!=NULL)
        {
            printf("%10d %20s %10d %10d
    ",ab->pid,ab->process_name,ab->start_addr,ab->size);
            ab=ab->next;
        }
    }
    
    void do_exit()
    {
        free(allocated_block_head);
        free(free_block);
        printf("over
    ");
    }
    
    int main()
    {
        char choice;
    
        free_block=init_free_block();
        while(1)
        {
            display_menu();
            scanf("%c",&choice);
            char c;while ((c = getchar()) != EOF && c != '
    ');
            switch(choice)
            {
                case '1':   set_mem_size();break;
                case '2':   set_algorithm();break;
                case '3':   new_process();break;
                case '4':   kill_process();break;
                case '5':   display_mem_usage();break;
                case '0':   do_exit();exit(0);
                default: break;
            }
    
        }
        return 0;
    }
    

    结果

    按如下过程测试

    1. 设定分配算法为FF
    2. 分配三个进程的内存大小为:100,200,300
    3. 然后删去pid2
    4. 设定分配算法为WF
    5. 分配pid4大小为200,观察是否从满足要求的最小块划分
    6. 删去pid4,选择分配算法BF
    7. 分配pid5大小为200,观察是否满足最优分配
    8. 删去pid3,观察能否合并
    9. 删去pid1,分配pid6大小为99,观察如何处理碎片
    10. 退出
      输出过长,省略
  • 相关阅读:
    facedetect
    gmm
    拉格朗日对偶
    基于 MeanShift 算法的目标跟踪问题研究
    视频目标跟踪算法综述
    AtCoder Beginner Contest 088 C Takahashi's Information
    L3-016. 二叉搜索树的结构
    垒骰子
    1130. Infix Expression (25)
    1129. Recommendation System (25)
  • 原文地址:https://www.cnblogs.com/yueshangzuo/p/8004911.html
Copyright © 2020-2023  润新知