基于可重定位分区分配算法的内存管理的设计与实现Word版Word文档下载推荐.docx
《基于可重定位分区分配算法的内存管理的设计与实现Word版Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于可重定位分区分配算法的内存管理的设计与实现Word版Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
如果回收区与插入点的后一个空闲分区相邻,应将回收区与插入点的后一分区合并,回收区的首址作为新空闲分区的首址,大小为二者之和;
如果回收区同时与插入点的前、后空闲分区相邻,应将三个分区合并,使用前一个分区的首址,取消后一个分区,大小为三者之和。
(3)紧凑模块
将内存中所有作业进行移动,使他们全都相邻接,把原来分散的多个空闲小分区拼接成一个大分区。
2.流程图
否
是是
3.代码实现
#include<
stdio.h>
stdlib.h>
time.h>
windows.h>
#defineTURE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
#defineOVERFLOW-2
#defineSIZE15
////////////////////////////进程表//////////////
intppNo=1;
//用于递增生成进程号
intpLength=0;
structPCB
{
intpNo;
//进程号(名)
intpSize;
//进程大小
intpOccupy;
//实际占用的内存
intpStartAddr;
//进程起始地址
intpState;
//进程状态
};
structPCBpList[200];
//////////////////空闲分区表部分///////////////
typedefintStatus;
typedefstructemptyNode
{//空闲分区结构体
intareaSize;
//空闲分区大小
intaStartAddr;
//空闲分区始址
structemptyNode*next;
}emptyNode,*LinkList;
intListDelete(structPCB*pList,inti);
//AAA/删除下标为i的进程
voidpSort(structPCB*pList);
//AAA/内存中的进程按始址递增排序
voidcompact(LinkList&
L,structPCB*pList);
//AAA/紧凑,内存中进程移动,修改进程数据结构;
空闲分区合并,修改空闲分区表数据结构
voidamalgamate(LinkList&
L);
//AAA/回收后进行合并空闲分区
voidrecycle(LinkList&
//AAA/回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中
StatusInitList(LinkList&
//1AAA/构造一个新的有头节点的空链表L
StatusClearList(LinkList&
//2AAA/将链表L重置为空表
StatusListInsert(LinkList&
L,LinkLists1);
//AAA/*****根据始址进行插入
voidDeleteElem(LinkList&
L,intaStartAddr);
//*****删除线性表中始址值为aStartAddr的结点
voidPrintList(LinkListL);
//AAA/*****输出各结点的值
voidcreatP(structPCB*p);
//AAA/初始化进程
intsearch(LinkList&
L,intpSize);
//AAA/检索分区表,返回合适分区的首址
intadd(LinkList&
//AAA/返回空闲分区总和
voidpListPrint(structPCB*pList);
//AAA/输出内存中空间占用情况
voiddistribute(LinkList&
L,structPCB*process);
intListDelete(structPCB*pList,inti)//AAA/删除下标为i的进程
for(;
i<
pLength-1;
i++){
pList[i]=pList[i+1];
}
pLength--;
}//ListDelete
voidpSort(structPCB*pList){//AAA/内存中的进程按始址递增排序
inti,j;
structPCBtemp;
for(i=0;
for(j=0;
j<
pLength-i-1;
j++){
if(pList[j].pStartAddr>
pList[j+1].pStartAddr){
temp=pList[j];
pList[j]=pList[j+1];
pList[j+1]=temp;
}
}
}
L,structPCB*pList){
printf("
进行紧凑\n"
);
//1、进程移动,修改进程数据结构
inti;
pList[0].pStartAddr=0;
//第一个进程移到最上面
pList[i+1].pStartAddr=pList[i].pStartAddr+pList[i].pOccupy;
//2、空闲分区合并,修改空闲分区表数据结构
LinkListp=L->
next,s;
intsumEmpty=0;
while(p!
=NULL)//求空闲区总和
{
sumEmpty+=p->
areaSize;
p=p->
next;
ClearList(L);
//清空空闲分区表
s=(LinkList)malloc(sizeof(emptyNode));
s->
aStartAddr=pList[pLength-1].pStartAddr+pList[pLength-1].pOccupy;
areaSize=sumEmpty;
ListInsert(L,s);
\n紧凑后的>
>
\n"
pListPrint(pList);
PrintList(L);
L){//AAA/回收后进行合并空闲分区
next,q=p->
while(q!
=NULL){
if(p->
aStartAddr+p->
areaSize==q->
aStartAddr){
p->
areaSize+=q->
DeleteElem(L,q->
aStartAddr);
//删除被合并的结点
q=p->
}else{
p=q;
q=q->
//AAA/回收,从进程表中删除进程,把释放出的空间插入到空闲分区链表中
intindex,delPNo,delPSize,delPOccupy,delPStartAddr;
LinkLists;
srand(time(0));
index=rand()%pLength;
delPNo=pList[index].pNo;
delPSize=pList[index].pSize;
delPOccupy=pList[index].pOccupy;
delPStartAddr=pList[index].pStartAddr;
________________________________________________________________________________"
回收内存进程P%d:
始址:
%dK占用:
%dKB\n"
delPNo,delPStartAddr,delPOccupy);
\n回收后>
ListDelete(pList,index);
//pListPrint(pList);
areaSize=delPOccupy;
aStartAddr=delPStartAddr;
amalgamate(L);
//输出内存中空间占用情况
///////////////////////////////////////////
L)//1AAA/构造一个新的有头节点的空链表L
L=(LinkList)malloc(sizeof(emptyNode));
//生成新节点(头结点)
if(!
L)returnERROR;
//申请内存失败
areaSize=900;
aStartAddr=0;
L->
next=s;
//头节点的指针域指向第一个结点
next=NULL;
returnOK;
}//InitList
L)//2AAA/将链表L重置为空表
LinkListp,r;
p=L->
r=p->
=NULL)
free(p);
if(r==NULL){
p=NULL;
p=r;
r=p->
}//ClearList
L,LinkLists1)
LinkListr=L,p=L->
//指针
areaSize=s1->
aStartAddr=s1->
aStartAddr;
if(p==NULL){
L->
s->
}else{
while(p!
{
if(s1->
aStartAddr<
p->
s->
next=r->
r->
break;
r=p;
//后移
if(p==NULL){
}//ListInsert2
L,intaStartAddr)//*****删除线性表中始址值为aStartAddr的结点
LinkListp=L,q;
while(p->
next!
q=p->
if(q->
aStartAddr==aStartAddr)
{
next=q->
free(q);
else
p=p->
}//DeleteElem
////////////////////////////////////////////////
voidPrintList(LinkListL)//AAA/*****输出各结点的值
{
\n空闲分区情况:
始址\t大小\n"
%dK\t%dKB\n"
p->
aStartAddr,p->
areaSize);
}//PrintList
voidcreatP(structPCB*p){//AAA/初始化进程
intsize;
srand(time(NULL));
size=rand()%7+1;
size*=10;
pNo=ppNo++;
pSize=size;
pOccupy=0;
pStartAddr=0;
pState=0;
L,intpSize){//检索分区表,返回合适分区的首址
areaSize>
=pSize){
returnp->
return-1;
//没有足够大的
L){//返回空闲分区总和
intsum=0;
sum+=p->
returnsum;
voidpListPrint(structPCB*pList){//AAA/输出内存中空间占用情况
\n进程分配情况:
进程\t始址\t占用\n"
for(inti=0;
pLength;
P%d\t%dK\t%dKB\n"
pList[i].pNo,pList[i].pStartAddr,pList[i].pOccupy);
L,structPCB*process){
=process->
pSize)
break;
%dKB<
%dKB"
process->
pSize,p->
if(p->
areaSize-process->
pSize<
=SIZE){
//不用分割全部分配(直接删除此空闲分区结点)
process->
pStartAddr=p->
//进程始址变化
pState=1;
pOccupy=p->
//进程实际占用内存为改空闲分区的大小
pList[pLength++]=*process;
//把进程加入进程列表
printf("
且%dKB-%dKB=%dKB<
%dKB则整区分配\n"
p->
areaSize,process->
pSize,SIZE);
pSort(pList);
\n分配后>
pListPrint(pList);
DeleteElem(L,p->
}else{//分割分配
pOccupy=process->
pSize;
//进程实际占用内存为该进程的大小
且%dKB-%dKB=%dKB>
%dKB则划分分配\n"
//进程排序
//compact(L,pList);
aStartAddr+=process->
//空闲分区始址变化
areaSize-=process->
pOccupy;
//空闲分区大小变化
}
intmain(){
//0、创建一个进程,参数随机数方式产生
structPCBp;
inti,num,dele,k,stAddr,flag;
LinkLists,L;
********************************可重定位分区分配********************************"
InitList(L))//初始化空闲分区表
创建表失败\n"
while
(1){
srand(time(0));
flag=rand()%100+1;
if(flag%2==0){
creatP(&
p);
//初始化进程
printf("
待装入作业:
%dSize=%dKB\n"
p.pNo,p.pSize);
//1、请求分配size
//2、检索空闲分区表(首次适应FF)
PrintList(L);
stAddr=search(L,p.pSize);
//得到足够大的分区的始址,没有则返回-1
if(stAddr==-1){//没有足够大的分区
if(add(L)>
=p.pSize){//空闲区总和足够大
没有足够大的空闲分区但空闲总和足够大\n"
//紧凑
compact(L,pList);
//按动态分区方式分配
distribute(L,&
//紧凑
}else{//空闲区总和不足
printf("
分配失败\n\n"
}
}else{//有足够大的
distribute(L,&
PrintList(L);
//紧凑
}
}else{//回收
if(pLength>
0){
recycle(L,pList);
//compact(L,pList);
无可回收内存!
"
system("
pause"
}//while
return0;
4.结果及其相关分析
图4.1
分析:
作业1大小为20KB。
找到足够大空闲分区,进行划分分配。
图4.2
作业2大小为70KB。
图4.3
先回收进程1大小为20KB,删除进程,并把释放的空闲分区插入空闲分区表;
再回收进程2大小为70KB,删除进程,并把释放的空闲分区插入空闲分区表;
图4.4
程序运行一段时间后的进程分配情况和空闲分区情况。
图4.5
程序运行一段时间后的进程分配情况和空闲分