模拟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;
}
结果
按如下过程测试
- 设定分配算法为FF
- 分配三个进程的内存大小为:100,200,300
- 然后删去pid2
- 设定分配算法为WF
- 分配pid4大小为200,观察是否从满足要求的最小块划分
- 删去pid4,选择分配算法BF
- 分配pid5大小为200,观察是否满足最优分配
- 删去pid3,观察能否合并
- 删去pid1,分配pid6大小为99,观察如何处理碎片
- 退出
输出过长,省略