内存管理实验

实验:内存管理实验

一、实验目的

1、通过本次试验体会操作系统中内存的分配模式;

2、掌握内存分配的方法(首次适应(FF),最佳适应(BF),最差适应(WF));

3、学会进程的建立,当一个进程被终止时内存是如何处理被释放块,并当内存不满足进程申请时是如何使用内存紧凑;

4、掌握内存回收过程及实现方法;

5、学会进行内存的申请释放和管理;

二、实验要求

1.运行如下的内存申请与释放序列:先设置内存大小为2048k,进程1申请500k,进程2申请300k,进程1完成,进程3申请200k,进程4申请100k,进程5申请300k;

2.分别选择不同的内存分配算法,输出上述序列的内存分配结果;

3.实现循环首次适应算法,并输出上述序列采用该分配算法后的结果。

三、实验代码

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>

#define PROCESS_NAME_LEN     32        /*进程名称的最大长度*/
#define MIN_SLICE            10        /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE     1024      /*默认内存的大小*/
#define DEFAULT_MEM_START    0         /*默认内存的起始位置*/

/* 内存分配算法 */
#define MA_FF      1
#define MA_BF      2
#define MA_WF      3
#define MA_NF      4

int mem_size=DEFAULT_MEM_SIZE;         /*内存大小*/
int ma_algorithm = MA_FF;              /*当前分配算法*/
int flag = 0;            		       /*设置内存大小标志*/
static int pid = 0;                    /*初始pid*/
int algorithm;

/*描述每一个空闲块的数据结构*/
struct free_block_type{
    int size;
    int start_addr;
    struct free_block_type *next;
};  


/*指向内存中空闲块链表的首指针*/
struct free_block_type *free_block;
struct free_block_type *NF_tmp=NULL;

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

struct allocated_block *find_process(int id)
{
    struct allocated_block *p;
	p=allocated_block_head;
	while(p!=NULL)
	{
	    if (p->pid==id)
            return p;
		p=p->next;
	}
	return NULL;
}

void swap(int *p,int *q)
{
    int temp;
      
     temp  =  *p;
       *p  =  *q;
       *q  =  temp;

    return;
}

void do_exit()
{
   exit(0);
}

/*初始化空闲块,默认为一块,可以指定大小及起始地址*/
struct free_block_type* init_free_block(int mem_size){
    struct free_block_type *fb;

    fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));
    if(fb==NULL){
        printf("No mem\n");
        return NULL;
        }
    fb->size = mem_size;
    fb->start_addr = DEFAULT_MEM_START;
    fb->next = NULL;
	//NF_tmp = fb;
    return fb;
}

/*显示菜单*/
display_menu()
{
    printf("\n");
    printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
    printf("2 - Select memory allocation algorithm\n");
    printf("3 - New process \n");
    printf("4 - Terminate a process \n");
    printf("5 - Display memory usage \n");
    printf("0 - Exit\n");
}

/*设置内存的大小*/
set_mem_size()
{
    int size;
    if(flag!=0){  //防止重复设置
        printf("Cannot set memory size again\n");
        return 0;
        }
    printf("Total memory size =");
    scanf("%d", &size);
	
    if(size>0) {
        mem_size = size;
        free_block->size = mem_size;
        }
    flag=1;  return 1;
}

/*按FF算法重新整理内存空闲块链表*/
rearrange_FF(){
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for FF \n");
    tmp = free_block;
	if(ma_algorithm==MA_FF||NF_tmp==NULL)
		NF_tmp = free_block;
    while(tmp!=NULL)
     { work = tmp->next;
       while(work!=NULL){
        if ( work->start_addr < tmp->start_addr)
		{ /*地址递增*/
            swap(&work->start_addr, &tmp->start_addr);
            swap(&work->size, &tmp->size);
        }
       
			work=work->next;            
        }
      tmp = tmp -> next;
     }
}

/*按BF最佳适应算法重新整理内存空闲块链表*/

rearrange_BF(){
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for BF \n");
    tmp = free_block;
	NF_tmp = free_block;
	while(tmp!=NULL)
     { work = tmp->next;
       while(work!=NULL){
        if ( work->size > tmp->size) { /*地址递增*/
            swap(&work->start_addr, &tmp->start_addr);
            swap(&work->size, &tmp->size);
            }
       
			work=work->next;            
        }
      tmp = tmp -> next;
     }
}



/*按WF算法重新整理内存空闲块链表*/

rearrange_WF(){
    struct free_block_type *tmp, *work;
    printf("Rearrange free blocks for WF \n");
    tmp = free_block;
	NF_tmp = free_block;
	while(tmp!=NULL)
     { work = tmp->next;
       while(work!=NULL){
        if ( work->size > tmp->size) 
		{ /*地址递增*/
            swap(&work->start_addr, &tmp->start_addr);
            swap(&work->size, &tmp->size);
            }
        else    
			work=work->next;            
        }
      tmp = tmp -> next;
     }
}

/*按指定的算法整理内存空闲块链表*/
rearrange(int algorithm){
    switch(algorithm){
        case MA_FF:  rearrange_FF(); break;
        case MA_BF:  rearrange_BF(); break;
        case MA_WF:  rearrange_WF(); break;
		case MA_NF:  rearrange_FF(); break;
        }
}

/* 设置当前的分配算法 */
set_algorithm(){
    
    printf("\t1 - First Fit\n");
    printf("\t2 - Best Fit \n");
    printf("\t3 - Worst Fit \n");
	printf("\t4 - Next Fit \n");
    scanf("%d", &algorithm);
    if(algorithm>=1 && algorithm <=4) 
		ma_algorithm=algorithm;
	else
		printf("选择不正确!\n");
	//按指定算法重新排列空闲区链表
    rearrange(ma_algorithm); 
}

/*分配内存模块*/
int allocate_mem(struct allocated_block *ab,int &ab_size){
    struct free_block_type *fbt, *pre, *temp,*work,*F=NULL; 
    int request_size=ab_size;
	if(NF_tmp==free_block||NF_tmp==NULL)
	{
		F=NULL;
		NF_tmp=free_block;
	}
	else 
		F=NF_tmp;
    fbt = NF_tmp;
	pre = fbt;			
	do
	{
		if(F!=NULL&&fbt==NULL)
			fbt=free_block;
        if(fbt->size>=request_size)
		{
			NF_tmp=fbt;
			if (fbt->size - request_size >= MIN_SLICE) /*分配后空闲空间足够大,则分割*/
			{
			    mem_size -= request_size;
				fbt->size -= request_size; 
			    ab->start_addr= fbt->start_addr;
				fbt->start_addr +=  request_size;
				NF_tmp=fbt;

			}  
			else  if ((fbt->size - request_size) < MIN_SLICE)
			   /*分割后空闲区成为小碎片,一起分配*/
			{
				
			    mem_size -= fbt->size;
				if(pre==free_block)
					free_block=fbt->next;
				else if(pre==fbt)
					for(pre=free_block;pre->next!=NULL;pre=pre->next)
						if(pre->next==fbt)
							break;
			    pre ->next= fbt->next;
				NF_tmp=fbt->next;
                ab->start_addr= fbt->start_addr;
				ab->size=fbt->size;
				free(fbt);
			}
			else
			{
				temp = free_block;
				while(temp!=NULL)
				{
					work = temp->next;
                    
					if(work!=NULL)/*如果当前空闲区与后面的空闲区相连,则合并*/
					{             
						if (temp->start_addr+temp->size == work->start_addr)
						{	 
							temp->size += work->size;
							temp->next = work->next;
							if(NF_tmp==work)
								NF_tmp=temp;
							free(work);
							continue;
						}
					}
                    
					temp = temp->next;
				}
				rearrange(algorithm); /*重新按当前的算法排列空闲区*/ 
			}
			return 1;
		}
		pre = fbt;
        fbt = fbt->next;
	}while(fbt!=F);
    return -1;
}

/*创建新的进程,主要是获取内存的申请数量*/
new_process(){
    struct allocated_block *ab;
    int size;
    int ret;
    ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
    if(!ab) 
		exit(-5);
    ab->next = NULL;
    pid++;
    sprintf(ab->process_name, "PROCESS-%02d", pid);
    ab->pid = pid;
    
    printf("Memory for %s:", ab->process_name);
    scanf("%d", &size);
    if(size>0) ab->size=size;
	else
		printf("输入大小不合法!\n");
    ret = allocate_mem(ab,ab->size);  /* 从空闲区分配内存,ret==1表示分配ok*/
/*如果此时allocated_block_head尚未赋值,则赋值*/
    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 2;
    }
    else if(ret==-1)
	{ /*分配不成功*/
        printf("Allocation fail\n");
        free(ab);
        return -1;
    }
    return 3;
}

/*将ab所表示的已分配区归还,并进行可能的合并*/
int free_mem(struct allocated_block *ab)
{
    int algorithm = ma_algorithm;
    struct free_block_type *fbt, *work;

    fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
    if(!fbt) return -1;
    fbt->size = ab->size;
    fbt->start_addr = ab->start_addr;
    /*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
    fbt->next = free_block;
    free_block=fbt;
    rearrange(MA_FF);
	fbt=free_block;
    while(fbt!=NULL){
        work = fbt->next;
        if(work!=NULL)
        {
            /*如果当前空闲区与后面的空闲区相连,则合并*/
             if(fbt->start_addr+fbt->size == work->start_addr)
                { 
                    fbt->size += work->size;
                    fbt->next = work->next;
					if(NF_tmp==work)
						NF_tmp=fbt;
                    free(work);
                    continue;
				}
        }
        fbt = fbt->next;
    }
    rearrange(algorithm); /*重新按当前的算法排列空闲区*/
    return 1;
    }


 /*释放ab数据结构节点*/
int dispose(struct allocated_block *free_ab)
{
    struct allocated_block *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;
}

/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */
display_mem_usage(){
    struct free_block_type *fbt=free_block;
    struct allocated_block *ab=allocated_block_head;
	printf("------------------------------------------------------\n");
	printf("\tFree Memory:\n");
	
    if(fbt==NULL) 
	{
		printf("内存已满,无空闲!!!\n");
	}
    
    /* 显示空闲区 */
    else
		printf("%20s %20s\n", "      start_addr", "       size");
    while(fbt!=NULL)
	{
        printf("%20d %20d\n", fbt->start_addr, fbt->size);
        fbt=fbt->next;
    }    
/* 显示已分配区 */
	printf("------------------------------------------------------\n");

    printf("\nUsed Memory:\n");
    printf("%10s %20s %20s %10s\n", "PID", "ProcessName", "start_addr", " size");
	while(ab!=NULL)
	{
      printf("%10d %20s %20d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
        ab=ab->next;
    }
    printf("------------------------------------------------------\n");
    return 0;
    }
          
/*删除进程,归还分配的存储空间,并删除描述该进程内存分配的节点*/
kill_process()
{
    struct allocated_block *ab;
    int pid;
    printf("Kill Process, pid=");
    scanf("%d", &pid);
    ab=find_process(pid);
    if(ab!=NULL)
        {
            free_mem(ab); /*释放ab所表示的分配区*/
            dispose(ab);  /*释放ab数据结构节点*/
        }
}

main()
{
    char choice;
    pid=0;
    free_block = init_free_block(mem_size); //初始化空闲区
    for(;;)
    {
		display_menu();	//显示菜单
		fflush(stdin);	//清空输入缓冲区
		choice=getchar();	//获取用户输入
		switch(choice)
		{
			case '1':  set_mem_size();                   break;       //设置内存大小
			case '2': set_algorithm();        flag=1;    break;	       //设置分配算法
			case '3': new_process();          flag=1;    break;	       //创建新进程
			case '4':   kill_process();       flag=1;    break;	       //删除进程
			case '5':   display_mem_usage();  flag=1;    break;         //显示内存使用
			case '0':   do_exit(); exit(0);                break;	    //释放链表并退出
			default: break;
		}
   } 
}

实验分析:

已有的三种内存管理的实现是通过采用不同的排序方式,从而查找时在已排好序的条件下进行查找;
而循环首次适应算法的排序方式和首次适应算法相同,不同点在于查找的起始位置,因此在修改过程中我添加了一个指针用来指明上次查找的位置,从而使下次查找时从此处开始。
需要注意当从特定位置开始查找时,查找结束的标志有所变化,前面几种结束的表示均是到链尾,而循环首次适应算法查找结束标志是再次查到特定位置。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值