模拟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. 退出
    输出过长,省略
原文地址:https://www.cnblogs.com/yueshangzuo/p/8004911.html