这个学期学习操作系统,其实主要就是系统对于一些情况的应对算法,我们要做的就是写代码模拟这个情况,来了解操作系统是怎么解决的。
一、简介
提高内存管理的效率始终是操作系统研究的重要课题之一,虚拟存储技术是用来提高存储容量的一种重要方法,所以,本项实验的目的是立地设计几个常用的存储分配算法,并用高级语言编写程序对各种算法进行分析比较,评测其性能的优劣,从而加深对这些算法的了解。
在存储管理中有两类主要算法:分区分配算法、请求式分页存储管理算法,本次讲解分区分配算法中的首次适应算法,最佳适应算法,回收算法
二、算法
首次适应算法(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;
}
本文深入探讨了操作系统中的内存管理技术,重点介绍了首次适应算法和最佳适应算法,通过代码实现展示了如何进行内存分配与回收,旨在帮助读者理解不同算法的优劣。
2万+

被折叠的 条评论
为什么被折叠?



