存储管理:首次适应算法和最佳适应算法

本文深入探讨了操作系统中的内存管理技术,重点介绍了首次适应算法和最佳适应算法,通过代码实现展示了如何进行内存分配与回收,旨在帮助读者理解不同算法的优劣。

这个学期学习操作系统,其实主要就是系统对于一些情况的应对算法,我们要做的就是写代码模拟这个情况,来了解操作系统是怎么解决的。

一、简介

提高内存管理的效率始终是操作系统研究的重要课题之一,虚拟存储技术是用来提高存储容量的一种重要方法,所以,本项实验的目的是立地设计几个常用的存储分配算法,并用高级语言编写程序对各种算法进行分析比较,评测其性能的优劣,从而加深对这些算法的了解。
在存储管理中有两类主要算法:分区分配算法、请求式分页存储管理算法,本次讲解分区分配算法中的首次适应算法,最佳适应算法,回收算法

二、算法

首次适应算法(First Fit):

该算法从空闲分区链首开始查找,直至找到一个能满足其大小要求的空闲分区为止。然后再按照作业的大小,从该分区中划出一块内存分配给请求者,余下的空闲分区仍留在空闲分区链中。
特点:该算法倾向于使用内存中低地址部分的空闲区,在高地址部分的空闲区很少被利用,从而保留了高地址部分的大空闲区。显然为以后到达的大作业分配大的内存空间创造了条件。
缺点:低地址部分不断被划分,留下许多难以利用、很小的空闲区,而每次查找又都从低地址部分开始,会增加查找的开销。

最佳适应算法(Best Fit):

该算法总是把既能满足要求,又是最小的空闲分区分配给作业。为了加速查找,该算法要求将所有的空闲区按其大小排序后,以递增顺序形成一个空白链。这样每次找到的第一个满足要求的空闲区,必然是最优的。孤立地看,该算法似乎是最优的,但事实上并不一定。因为每次分配后剩余的空间一定是最小的,在存储器中将留下许多难以利用的小空闲区。同时每次分配后必须重新排序,这也带来了一定的开销。
特点:每次分配给文件的都是最合适该文件大小的分区。
缺点:内存中留下许多难以利用的小的空闲区。

回收算法:

即把已有分区释放,合并两个及以上空闲分区:合并2个或合并3个或无法合并。主要问题在于各种情况的讨论。我采用的方法不是以回收那个区为中心来判断,我是从头到尾来判断,我认为这样更利于理解。

三、结果

这里只展示首次适应了。
在这里插入图片描述
在这里插入图片描述

四、代码

#include<iostream>
#include<stdlib.h>
using namespace std;
#define Free 0 //空闲状态
#define Busy 1 //已用状态
#define OK 1    //完成
#define ERROR 0 //出错
#define MAX_length 640  //定义最大主存信息640KB
typedef int Status;//方便改类型
typedef struct FreAarea//定义一个空闲区说明表结构
{
	long size;   //分区大小
	long address; //分区地址
	int state;   //状态
}ElemType;

typedef struct DuLNode// 线性表的双向链表存储结构
{
	ElemType data;
	struct DuLNode *prior; //前趋指针
	struct DuLNode *next;  //后继指针
}


DuLNode, *DuLinkList;//DuLinkList是一个指针
DuLinkList block_first; //头结点
DuLinkList block_last;  //尾结点

Status Alloc(int);//内存分配
Status free(int); //内存回收
Status First_fit(int);//首次适应算法
Status Best_fit(int); //最佳适应算法
Status Initblock();//开创空间表


Status Initblock()//开创带头结点的内存空间链表
{
	block_first = (DuLinkList)malloc(sizeof(DuLNode));
	block_last = (DuLinkList)malloc(sizeof(DuLNode));
	block_first->prior = NULL;
	block_first->next = block_last;
	block_last->prior = block_first;
	block_last->next = NULL;
	block_last->data.address = 0;
	block_last->data.size = MAX_length;
	block_last->data.state = Free;
	return OK;
}

Status Alloc(int ch)//分配主存
{
	int request = 0;
	cout << "请输入需要分配的主存大小(单位:KB):"<<endl;
	cin >> request;
	if (request<0 || request == 0)
	{
		cout << "分配大小不合适,请重试!" << endl;
		return ERROR;
	}
	if (ch == 1) //选择首次适应算法
	{
	    if (First_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;
	}
	else //选择最佳适应算法
	{
		if (Best_fit(request) == OK) cout << "分配成功!" << endl;
		else cout << "内存不足,分配失败!" << endl;
		return OK;
	}
}

Status First_fit(int request)//首次适应算法
{
	//为申请作业开辟新空间且初始化
	DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));
	temp->data.size = request;
	temp->data.state = Busy;

	DuLNode *p = block_first->next;
	while (p)
	{
		if (p->data.state == Free && p->data.size == request)
		{//有大小恰好合适的空闲块
			p->data.state = Busy;
			return OK;
			break;
		}
		if (p->data.state == Free && p->data.size>request)
		{//有空闲块能满足需求且有剩余
			temp->prior = p->prior;
			temp->next = p;
			temp->data.address = p->data.address;
			p->prior->next = temp;
			p->prior = temp;
			p->data.address = temp->data.address + temp->data.size;
			p->data.size -= request;
			return OK;
			break;
		}
		p = p->next;
	}
	return ERROR;
}


Status Best_fit(int request)//最佳适应算法
{
	DuLinkList temp = (DuLinkList)malloc(sizeof(DuLNode));
	temp->data.size = request;
	temp->data.state = Busy;
	DuLNode *p = block_first->next;
	DuLNode *q = NULL; //记录最佳插入位置

	while (p) //初始化最小空间和最佳位置
	{
		if (p->data.state == Free && (p->data.size >= request))
		{
			if (q == NULL)
			{
				q = p;
			}
			else if (q->data.size > p->data.size)
                {
                    q = p;
                }
		}
		p = p->next;
	}

	if (q == NULL) return ERROR;//没有找到空闲块
	else if (q->data.size == request)
	{
		q->data.state = Busy;
		return OK;
	}
	else
	{
		temp->prior = q->prior;
		temp->next = q;
		temp->data.address = q->data.address;
		q->prior->next = temp;
		q->prior = temp;
		q->data.address += request;
		q->data.size -= request;
		return OK;
	}
	return OK;
}

Status free(int flag)//主存回收
{
	DuLNode *p = block_first;
	for (int i = 0; i <= flag; i++)
		if (p->next != NULL)
			p = p->next;
		else
			return ERROR;
    if(p->data.state == Free)return OK;//本身已经是空闲态了
	p->data.state = Free;
	if(block_first->next==block_last)return OK;//如果只有一个分区,就可以直接返回了
	//以免下面的y=t->next出现空指针
    for(DuLNode *t=block_first->next;t!=block_last;t=t->next)
    {
        DuLNode *y=t->next;
        while(t->data.state==Free&&y->data.state==Free)
        {
            if(y==block_last)//如果是最后一个
            {
                t->data.size += y->data.size;
                t->next=y->next;
                block_last=t;//!一定要记得更新尾指针,要不然特殊情况就出错了
                return OK;
            }
            else
            {
                t->data.size += y->data.size;
                t->next=y->next;
                y->next->prior=t;
                y=y->next;
            }
        }
    }
	return OK;
}

int main()//主函数
{
	int ch;//算法选择标记
	cout << "请输入所使用的内存分配算法:\n";
	cout << "(1)首次适应算法\n(2)最佳适应算法\n";

	cin >> ch;
	while (ch<1 || ch>2)
	{
		cout << "输入错误,请重新输入所使用的内存分配算法:\n";
		cin >> ch;
	}

	Initblock(); //开创空间表
	int choice;  //操作选择标记

	while (1)
	{
		int flag = 0;
        cout << "主存分配情况:\n";
        cout << "++++++++++++++++++++++++++++++++++++++++++++++\n";
        DuLNode *p = block_first->next;
        cout << "分区号\t起始地址\t分区大小\t状态\n";
        while (p)
        {
            cout << "  " << flag++ << "\t";
            cout << "  " << p->data.address << "\t\t";
            cout << " " << p->data.size << "KB\t\t";
            if (p->data.state == Free) cout << "空闲\n";
            else cout << "已分配\n";
            p = p->next;
        }
        cout << "++++++++++++++++++++++++++++++++++++++++++++++\n";

		cout << "请输入您的操作:\n";
		cout << "1: 分配内存\n2: 回收内存\n0: 退出\n";

		cin >> choice;
		if (choice == 1) Alloc(ch); // 分配内存
		else if (choice == 2)  // 内存回收
            {
                int num;
                cout << "请输入您要释放的分区号:"<<endl;
                cin >> num;
                free(num);
            }
            else if (choice == 0) break; //退出
                else //输入操作有误
                {
                    cout << "输入有误,请重试!" << endl;
                    continue;
                }
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值