一、项目名称:可变分区存储管理模拟系统
二、项目描述:
本系统实现了对操作系统对于动态分区分配的模拟,用户可以选择不同的分区模拟方法。要求不同的内存空
间,程序会对其进行相应的动态分区分配。所谓动态分区分配是根据进程的实际需要,动态地为之分配内存
空间。在实现可变分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操
作这样三个问题。下面详细介绍这三个问题。
2.1 所用数据结构
空闲分区链:
为了实现对空闲分区的分配和链接,在每个分区中添加一些描述信息,设置一些用于
控制分区分配的信息为了检索方便,在分区尾部重复设置状态位和分区大小表目。当分
区被分配出去以后,修改分区状态。
2.2 分区分配算法
2.2.1 首次适应算法:
在分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再
按照作业的大小,从该分区中划出一块内存空间分配给请求者,余下的空闲分区仍留在空闲链
中。若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。
2.2.2 最佳适应算法:
所谓“最佳”是指每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区分配给作
业,避免“大材小用” 。为了加速寻找,该算法要求将所有的空闲分区按其容量以从小到大的
顺序形成一空闲分区链。这样,第一次找到的能满足要求的空闲区,必然是最佳的。孤立地看,
最佳适应算法似乎是最佳的,然而在宏观上却不一定。因为每次分配后所切割下来的剩余部分
总是最小的,这样,在存储器中会留下许多难以利用的小空闲区。
2.2.3 最差适应算法:
最坏适应分配算法要扫描整个空闲分区表或链表,总是挑选一个最大的空闲区分割给作业使用,
其优点是可使剩下的空闲区不至于太小,产生碎片的几率最小,对中、小作业有利,同时最坏
适应分配算法查找效率很高。该算法要求将所有的空闲分区按其容量以大到小的顺序形成一空
闲分区链,查找时只要看第一个分区能否满足作业要求。
2.3 分区的回收
分区回收时分为三种不同的情况:
2.3.1 要回收的分区的上一个分区是空闲分区
回收区与插入点的前一个空闲分区 F 1 相邻接。此时应将回收区与插入点的前一分区合并,不
必为回收分区分配新表项,而只需修改其前一分区 F 1 的大小。
2.3.2 要回收的分区的下一个分区是空闲分区
回收分区与插入点的后一空闲分区 F 2 相邻接,此时也可将两分区合并,
形成新的空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和。
2.3.3 要回收的分区的上下分区是不是空闲分区
回收区既不与 F 1 邻接,又不与 F 2 邻接。这时应为回收区单独建立一新表项,填写
回收区的首址和大小,并根据其首址插入到空闲链中的适当位置。
三、程序逻辑框图
分配分区功能:
显示分配界面:
内存回收
五、程序主要代码
//首次适应算法:
void MemList::firstFit(unsigned int asksize)
{
}
int jobid;
cinTheJobid(jobid);
head.sort(ComByAddr());
list
::iterator it;
for(it=head.begin();it!=head.end();it++)
{
//表示这个分区可以分配;
if((*it)->getstate()==FREE
&&(*it)->getMemSize() - asksize > minLastsize)
{
//之前的空闲分区分配给它了
(*it)->setState(BUSY);
(*it)->setMemsize(asksize);
(*it)->setJobid(jobid);
//新增一个空闲分区
int beginaddr=(*it)->getBeginAddress()+asksize;
int lastsize=(*it)->getMemSize() - asksize;
MemNode *node=new MemNode(FREE,beginaddr,lastsize,0);
head.push_back(node);
}
else
{
continue;
}
if(it==head.end())
{
cout<<"分配失败!"<head.sort(ComBySize());
head.sort(ComBySize());
cinTheJobid(jobid);
list::iterator it;
for(it=head.begin();it!=head.end();it++)
{
//表示这个分区可以分配;
if((*it)->getstate()==FREE
&&(*it)->getMemSize() - asksize > minLastsize)
{
//之前的空闲分区分配给它了
(*it)->setState(BUSY);
(*it)->setMemsize(asksize);
(*it)->setJobid(jobid);
//新增一个空闲分区
int beginaddr=(*it)->getBeginAddress()+asksize;
int lastsize=(*it)->getMemSize() - asksize;
MemNode *node=new MemNode(FREE,beginaddr,lastsize,0);
head.push_back(node);
}
else
{
continue;
}
if(it==head.end())
{
cout<<"分配失败!"<::iterator it;
for(it=head.begin();it!=head.end();it++)
{
//表示这个分区可以分配;
if((*it)->getstate()==FREE
&&(*it)->getMemSize() - asksize > minLastsize)
{
//之前的空闲分区分配给它了
(*it)->setState(BUSY);
(*it)->setMemsize(asksize);
(*it)->setJobid(jobid);
//新增一个空闲分区
int beginaddr=(*it)->getBeginAddress()+asksize;
int lastsize=(*it)->getMemSize() - asksize;
MemNode *node=new MemNode(FREE,beginaddr,lastsize,0);
head.push_back(node);
}
else
{
continue;
}
if(it==head.end())
{
cout<<"分配失败!"<>jobid;
list::iterator it;
for(it=head.begin();it!=head.end();++it)
{
if((*it)->getJobid()==jobid)
break;
}
if(it==head.end())
{
cout<<"输入的 id 号不正确"<::iterator itpre,itnext;
it--;
itpre=it;
++it;
++it;
itnext=it;
it--;
//前面为空闲
if((*itpre)->getstate()==FREE)
{
unsigned int oldsize=(*itpre)->getMemSize();
unsigned int newsize=oldsize+(*it)->getMemSize();
(*itpre)->setMemsize(newsize);
delete *it;
head.erase(it);//删除之前得释放内丰
}
//后面为空闲
if((*itnext)->getstate()==FREE)
{
(*it)->setState(FREE);
unsigned int oldsize=(*it)->getMemSize();
unsigned int newsize=oldsize+(*itnext)->getMemSize();
(*it)->setMemsize(newsize);
delete *itnext;
head.erase(itnext);
}
else
{
delete *it;
head.erase(it);
}
cout<<"已经回收"<