操作系统实验:模拟内存管理设计与实现

模拟内存管理设计与实现:
模拟实现动态分区内存管理机制。设计和实现关于内存管理的内存布局初始化及内存申请分配、内存回收等基本功能操作函数,尝试对 256MB 的用户内存空间进行动态分区方式模拟管理。内存分配的基本单位为 1KB,同时要求支持至少两种分配策略,并进行测试和对不同分配策略的性能展开比较评估。要求随机发生进程创建事件(包括进程运行时间及申请内存空间大小)。

    首次适应(First Fit)算法:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。 

    最佳适应(Best Fit)算法:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区。 

    最坏适应(Worst Fit)算法:又称最大适应(Largest Fit)算法,空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。

// 模拟内存管理.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


typedef unsigned long DIZHI;  //地址类型的设置

int num = 0;  //进程数量
int c;  //选择算法
int times = 0;  //查找次数

typedef struct freenode {  //空闲内存链表
	int size;  //空闲地址块的大小
	int address;  //起始地址
	struct freenode* next;  //指向下一个空闲地址块
};
freenode *free_L = NULL;  //空闲链表

struct busynode {  //内存占用链表
	int pid;  //进程号
	int size;  //地址块的大小
	int address;  //起始地址
	struct busynode* next;  //指向下一个被占用的地址块
};
busynode* busy_L = NULL;  //进程内存链表


/*设计一定的数据结构以描述256MB内存空间的使用状况,并设计和构建函数void ChuShuHuaNC
实现内存布局的初始化。假定内存空间的低址部分56MB(即0~56M-1)作为系统区和不参与分配过程。*/
void ChuShiHuaNC(DIZHI zKS_KYNC, DIZHI zJS_KYNC)
{
	struct freenode *p;
	busy_L = (busynode*)malloc(sizeof(busynode));
	free_L = (freenode*)malloc(sizeof(freenode));
	p = (freenode*)malloc(sizeof(freenode));

	busy_L->next = NULL;  //初始化占用地址块链表
	free_L->next = p;  //初始化空闲地址链表
	p->size = zJS_KYNC - zKS_KYNC;  //空闲区的大小
	p->address = zKS_KYNC;  //0~55不参与内存分配过程
	printf("内存空间(%d~%dM)参与实际分配过程\n",zKS_KYNC,zJS_KYNC);
	p->next = NULL;
}

void FF() {
	freenode* fbh = free_L->next;
	freenode* fbp = free_L->next;
	int sizep;
	int addrp;
	while (fbh != NULL) {
		while (fbp->next != NULL) {
			if (fbp->address>fbp->next->address) {
				addrp = fbp->address;
				fbp->address = fbp->next->address;
				fbp->next->address = addrp;
				sizep = fbp->size;
				fbp->size = fbp->next->size;
				fbp->next->size = sizep;
			}
			fbp = fbp->next;
		}
		fbp = free_L->next;
		fbh = fbh->next;
	}
	while (fbh != NULL) {
		printf("%d,%d", fbh->size, fbh->address);
		fbh = fbh->next;
	}
}

void BF() {
	freenode* fbh = free_L->next;
	freenode* fbp = free_L->next;
	int sizep;
	int addrp;
	while (fbh != NULL) {
		while (fbp->next != NULL) {
			if (fbp->size > fbp->next->size) {
				addrp = fbp->address;
				fbp->address = fbp->next->address;
				fbp->next->address = addrp;
				sizep = fbp->size;
				fbp->size = fbp->next->size;
				fbp->next->size = sizep;
			}
			fbp = fbp->next;
		}
		fbp = free_L->next;
		fbh = fbh->next;
	}
	while (fbh != NULL) {
		printf("%d,%d", fbh->size, fbh->address);
		fbh = fbh->next;
	}
}

void WF() {
	freenode* fbh = free_L->next;
	freenode* fbp = free_L->next;
	int sizep;
	int addrp;
	while (fbh != NULL) {
		while (fbp->next != NULL) {
			if (fbp->size<fbp->next->size) {
				addrp = fbp->address;
				fbp->address = fbp->next->address;
				fbp->next->address = addrp;
				sizep = fbp->size;
				fbp->size = fbp->next->size;
				fbp->next->size = sizep;
			}
			fbp = fbp->next;
		}
		fbp = free_L->next;
		fbh = fbh->next;
	}
	while (fbh != NULL) {
		printf("%d,%d", fbh->size, fbh->address);
		fbh = fbh->next;
	}
}

/*设计和实现内存申请分配函数DIZHI ShenQingNC(unsigned long zDX),内存分配的基本单位为1KB,
同时要求支持至少两种分配策略(如首次适应、循环首次适应、最佳适应、最坏适应等),若分配失败则返回NULL。*/
DIZHI ShenQingNC(unsigned long zDX)
{
	printf("\n创建新的进程:所需空间为%d\n",zDX);

	busynode *b = (busynode*)malloc(sizeof(busynode));
	busynode *a = (busynode*)malloc(sizeof(busynode));

	switch (c){
	case 1: FF(); 
		break;
	case 2: BF(); 
		break;
	case 3: WF(); 
		break;
	default: printf("输入错误!\n"); 
		return NULL;
	}
	freenode *p = free_L->next;
	while (p != NULL)
	{
		if (p->size >= zDX)
		{
			a->next = busy_L->next;
			busy_L->next = a;
			
			num++;  //进程数量增加
			p->size -= zDX;
			a->size = zDX;
			a->address = p->address;
			p->address = p->address + a->size;
			printf("将首地址为%d,大小为%d的内存空间分配给进程!\n\n", a->address, a->size);
			return 1;
		}
		p = p->next;
		times++;
	}
	printf("内存空间不足!\n");
	free(a);
	return 0;
}

/*设计和实现内存回收函数void HuiShouNC(DIZHI zKSDZ) ,若回收分区与其它空闲分区相邻接,则采取合并措施。*/
void HuiShouNC(DIZHI zKSDZ)
{
	int i = 0;
	int m = rand()%num;  //随机指定进程号
	busynode *b = (busynode*)malloc(sizeof(busynode)),
		*c = (busynode*)malloc(sizeof(busynode));
	printf("回收进程%d所分配的内存\n",m);
	c = busy_L;
	b = c->next;
	while (b != NULL)
	{
		if (i == m)
			break;
		i++;
		c = b;
		b = b->next;
	}
	if (b->size == NULL)
	{
		printf("指定进程时出错!\n");
		return;
	}
	else
	{
		c->next = b->next;  //回收算法 完成地址块的合并
		
		num--;
		freenode *t = (freenode*)malloc(sizeof(freenode));
		t->next = free_L->next;
		free_L->next = t;
		t->size = b->size;
		t->address = b->address;
		free(b);
		printf("回收完成!\n");
		FF();  //地址递增排序
		freenode *p,*q;
		q = free_L->next;
		p = q->next;
		while (p != NULL)   //合并内存
		{
			if (q->address + q->size == p->address)
			{
				printf("合并地址为%d和%d的空间!\n",q->address,p->address);
				q->size += p->size;
				q->next = p->next;
				free(p);
				p = q->next;
				continue;
			}
			q = p;
			p = p->next;
		}
	}
}
void display_memory()
{
	int s = 0;
	busynode *a;
	a = busy_L->next;
	printf("\n----------------------------\n");
	while (a != NULL)
	{
		printf("进程%d:起始地址为%d,大小为%d\n",s++,a->address,a->size);
		a = a->next;
	}
	printf("----------------------------\n\n");
}
int main()
{
	printf("地址分配实验:\n");
	printf("初始化内存空间:(%d~%dM)\n",0,256);
	ChuShiHuaNC(56,256);  //初始化内存空间,0~56M-1不参与分配过程

	printf("选择分配策略: 1.FF 2.BF 3.WF\n");
	scanf("%d", &c);
/*基于不同的内存分配策略形成不同版本的内存管理器,并根据内存平均利用率和
分配查找分区比较次数等指标展开测试和对不同分配策略的内存管理器性能进行评估。*/
	double aver = 0;  //平均内存利用率
	int x = 0;
	double size = 0;
	int tag = 0;
	while(1)
	{
		display_memory();
//		Sleep(3000);
		if (num>0)  //产生随机数,并根据该值确定是申请内存还是回收内存
		{
			int ss = rand() % 7;
			if (ss%2 == 0)
			{
				int m = rand()%80;
				if (m != 0)
				{
					ShenQingNC(m);
					size += m;
					tag++;
				}
			}
			else
			{
				int n = rand() % num;
				HuiShouNC(n);
			}
		}
		else
		{
			int m = rand() % 80;
			if (m != 0)
			{
				ShenQingNC(m);
				size += m;
				tag++;
			}
		}
		//性能指标计算:内存平均利用率&&查找次数
		//计算内存平均利用率
		busynode *it = busy_L->next;
		double P = 0;
		while (it != NULL)
		{
			P += it->size;
			it = it->next;
		}
		printf("内存利用率:%.3f\n",P/200);
		x++;
		aver += P/200;
		if (x == 10000)
			break;
	}
	printf("\n该方法平均内存申请大小:%.3f,平均内存利用率:%.3f,查找次数:%d\n",size/tag, aver/x ,times);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35014850/article/details/81145667