动态分区分配是指在系统运行的过程中建立分区,并使分区的大小刚好与作业的大小相等。
分区的分配:
系统初启后,除操作系统占用一个分区外,其余存储区为一个大的空闲区。
分区的分配是指系统根据用户的请求,在空闲分区表或空闲分区队列中寻找一个满足用户要求的空闲分区,把这个空闲分区分配给用户。
以空闲分区表为例,当用户要求一个大小为SIZE的存储空间时,系统查询空闲分区表,找一个大于或等于SIZE的空闲区。
分配时的三种情况:
一是系统中无满足要求的空闲分区,则分配失败。
二是空闲区大小与SIZE相等,则修改空闲分区表相应表目,向用户返回该空闲分区首址,表示此空闲分区已分给了要求的用户。
其三是空闲分区大于SIZE,这时将空闲分区一分为二。
将一个空闲分区分成二部分有两种办法:
从空闲分区的上部开始划出SIZE大小的空闲分区给用户;
从空闲分区的底部开始向上划出SIZE大小的空闲分区给用户。
在下面的代码中所采取的是第二种办法,因为这样比较方便,只需要修改空闲分区的大小即可,而不需要修改首地址。
分区的回收:
当某个进程释放某存储区时,系统首先检查释放区是否与系统中的空闲区相邻,若相邻则把释放区合并到相邻的空闲区中去,否则把释放区作为一个空闲区插入到空闲分区表的适当位置。
模拟对1MB内存的管理,实现步骤如下:
1、定义一个结构体表示空闲内存块的信息,包括内存块的起始地址和内存块的大小;定义另外一个结构体来表达进程的信息,包括进程的id、进程的大小和进程被分配内存的起始位置。分别用一个长度为1000的结构体数组表示所有空闲内存块和进程的信息。
struct Memory_block
{
int st;
int amount;
}m[1000];//内存块的首地址和大小。
struct Progress
{
int id;
int amount;
pair<int, int> st_ed;
}p[1000];
2、空闲内存块初始化数量为1,起始地址为0,大小为1024。
3、程序输入格式的规定,第一行先输入一个正整数n表示操作的次数,第二行输入本次程序运行要使用的适应算法。
接下来输入n个操作:操作为申请内存或者释放内存,如果想为某一进程申请内存,则在当前行输入in,然后在下一行以空格为间隔输入两个整数,分别代表进程的id和大小(kb);如果想结束某个进程并释放内存,则在当前行输入out,然后在下一行输入要释放进程的id。
3、当释放某一进程的内存时,先判断是否有和这片内存紧密相邻(即两者之间没有空隙)的空闲内存块。如果有,则进行相应的合并操作,将这片内存合并到空闲内存块中;如果没有,则生成一个新的空闲内存块,内存块的首地址为该片内存的首地址,大小为该片内存的大小。释放内存的方法是通用的,不受分配内存时使用的算法种类影响。
4、当为某一进程申请内存时:
①first-fit算法:按照首地址从前往后遍历空闲内存块,如果发现当前内存块大小能够满足该进程,则将该进程分配到当前内存块中,并break退出循环。如果所有内存块大小都小于该进程,则分配失败。
②best-fit算法:遍历所有的空闲内存块,找到能够满足该进程的最小的内存块,并将该进程分配到这个内存块中。如果所有内存块大小都小于该进程,则分配失败。
③worst-fit算法:遍历所有空闲内存块,找到最大的那个内存块,将该进程分配到这个内存块中。如果所有内存块大小都小于该进程,则分配失败。
测试输入:
7
first-fit
in
1 400
in
2 100
in
3 200
in
4 10
out
3
out
1
in
5 100
经整理后的输出结果:
附完整代码:
#include
#include
using namespace std;
const int MAX=1024;
const int INF=0x3f3f3f3f;
struct Memory_block
{
int st;
int amount;
}m[1000];//内存块的首地址和大小。
int cnt_m=0;//内存块的数量。
struct Progress
{
int id;
int amount;
pair<int, int> st_ed;
}p[1000];
int cnt_p=0;//进程的数量。
bool cmp1(Memory_block m1,Memory_block m2)
{
return m1.st<m1.st;
}
void showInfos()
{
cout<<"---empty memory section (start,amount) :"<<endl;
for(int i=0; i<cnt_m; i++)
{
if(m[i].amount>0)
{
printf( "---(%d,%d)\n", m[i].st, m[i].amount);
}
}
cout<<endl;
cout<<"---progress in memory (start, end) :"<<endl;
for(int i=0; i<cnt_p; i++)
{
printf( "---id:%d (%d,%d)\n", p[i].id, p[i].st_ed.first, p[i].st_ed.second);
}
}
void first_fit(Progress &p)
{
for(int i=0;i<cnt_m;i++)
{
if(m[i].amount>=p.amount)
{
p.st_ed.second = m[i].st + m[i].amount;
p.st_ed.first = p.st_ed.second - p.amount;
m[i].amount-= p.amount;
printf("---progress %d get memory from %d to %d\n", p.id, p.st_ed.first, p.st_ed.second);
return ;
}
}
printf("---applying for memory failed\n");
}
void best_fit(Progress &p)
{
int minm=INF;
int x=-1;
for (int i=0; i<cnt_m; i++)
{
if(m[i].amount>=p.amount&&minm>m[i].amount)
{
minm=m[i].amount;
x=i;
}
}
if(x==-1)
{
printf("---applying for memory failed\n");
return ;
}
p.st_ed.second = m[x].st + m[x].amount;
p.st_ed.first = p.st_ed.second - p.amount;
m[x].amount-= p.amount;
printf("---progress %d get memory from %d to %d\n", p.id, p.st_ed.first, p.st_ed.second);
}
void worst_fit(Progress &p)
{
int maxm=-1;
int x=-1;
for(int i=0; i<cnt_m; i++)
{
if(m[i].amount>maxm)
{
maxm=m[i].amount;
x=i;
}
}
if(x!=-1 && m[x].amount >= p.amount)
{
p.st_ed.second = m[x].st + m[x].amount;
p.st_ed.first = p.st_ed.second - p.amount;
m[x].amount-= p.amount;
printf("---progress %d get memory from %d to %d\n", p.id, p.st_ed.first, p.st_ed.second);
}
else
{
printf("---applying for memory failed\n");
}
}
void release(int id)
{
int st, ed, amount;
bool flag=true;
for (int i = 0; i < cnt_p; i++)
{
if(p[i].id==id)
{
st=p[i].st_ed.first;
ed=p[i].st_ed.second;
amount=p[i].amount;
p[i].st_ed.first=-1;
p[i].st_ed.second=-1;
flag=false;
break;
}
}
if(flag)
{
cout<<"---releasing the memory failed"<<endl;
return ;
}
int last = -1;
for (int i = 0; i < cnt_m; i++)
{
if(m[i].st + m[i].amount == st)
{
last=i;
break;
}
}
int next = -1;
for (int i = 0; i < cnt_m; i++)
{
if(m[i].st == ed)
{
next=i;
break;
}
}
if(next!=-1 && last!=-1)
{
m[last].amount+= amount+m[next].amount;
m[next].amount=0;
}
else if(last != -1)
{
m[last].amount+= amount;
}
else if(next != -1)
{
m[next].st=st;
m[next].amount+=amount;
}
else
{
m[cnt_m++]={st,amount};
sort (m, m+cnt_m, cmp1);
}
printf("---progress %d has been moved out of memory\n", id);
}
int main()
{
m[cnt_m++]={0,MAX};
cout<<"--please input the count of operations:"<<endl;
int t;
cin>>t;
string type;
cout<<"--please input the type of algorithm, best-fit, worst-fit, or first-fit:"<<endl;
cin>>type;
while (t--)
{
cout<<"--please input the type of this operation:"<<endl;
//输入in代表为某个新进程申请内存
//输入out代表将某个旧进程的内存释放
string s;
cin>>s;
if(s=="in")
{
cout<<"--please input the id and the amount of this progress:"<<endl;
int id;
int amount;
cin>>id>>amount;
p[cnt_p++]={id,amount};
if(type == "first-fit")
{
first_fit(p[cnt_p-1]);
}
else if(type == "worst-fit")
{
worst_fit(p[cnt_p-1]);
}
else if(type == "best-fit")
{
best_fit(p[cnt_p-1]);
}
else
{
cout<<"error input!"<<endl;
}
}
else if(s=="out")
{
cout<<"--please input the id of the progress:"<<endl;
int id;
cin>>id;
release(id);
}
else
{
cout<<"error in inputing!"<<endl;
}
}
cout<<endl;
showInfos();
}