一、动态分区分配算法的背景
为了能将用户程序装入内存,必须为它分配一定大小的内存空间。连续分配方式是最早出现的一种存储器分配方式, 曾被广泛应用于上世纪60~ -80 年代的OS中,该分配万式为个用户程序分配 一个连续的内存空间, 即程序中代码或数据的逻辑地址相邻,体现在内存空间分配时物理地址的相邻。连续分配方式可分为四类:单一连续分配、固定分区分配、动态分区分配以及动态可重定位分区分配算法四种方式,其中动态分区分配算法就是此实验的实验对象。
动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操作这样三方面的问题。
动态分区分配又称为可变分区分配,它是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配与回收操作这样三方面的问题。
二、四种分配算法原理
1.首次适应算法(First Fit)
将空闲分区链以地址递增的顺序连接;在进行内存分配时,从链首开始顺序查找,直到找到一块分区的大小可以满足需求时,按照该作业的大小,从该分区中分配出内存,将剩下的空闲分区仍然链在空闲分区链中。
2.循环首次适应算法(Next Fit)
分配内存时不是从链首进行查找可以分配 内存的空闲分区,而是从上一次分配内存的空闲分区的下一个分区开始查找,直到找到可以为该进程分配内存的空闲分区;
3.最佳适应算法(Best Fit)
将空闲分区链中的空闲分区按照空闲分区由小到大的顺序排序,从而形成空闲分区链。每次从链首进行查找合适的空闲分区为作业分配内存,这样每次找到的空闲分区是和作业大小最接近的,所谓“最佳”。
4.最坏适应算法(Worst Fit)
与最佳适应算法刚好相反,将空闲分区链的分区按照从大到小的顺序排序形成空闲分区链,每次查找时只要看第一个空闲分区是否满足即可。
三、四种算法过程记录
动态内存信息:
分区个数:5
各分区首址:0 50 190 340 530
各分区大小:130 70 140 80 20
1.首次适应算法(First Fit)
2.循环首次适应算法(Next Fit)
3.最佳适应算法(Best Fit)
4.最坏适应算法(Worst Fit)
四、算法的优劣比较
1.首次适应算法(First Fit)
优点:高址部分的大的空闲分区得到保留,为大作业的内存分配创造了条件;
缺点:
(1)每次都是优先利用低址部分的空闲分区,造成低址部分产生大量的外碎片。
(2)每次都是从低址部分查找,使得查找空闲分区的开销增大;
2.循环首次适应算法(Next Fit)
优点:
(1)使得空闲分区分布更加均匀;
(2)空闲分区的查找开销小;
缺点:高址部分的大空闲分区被分小,使得大作业进入无法分配内存;
3.最佳适应算法(Best Fit)
优点:第一次找到的空闲分区是大小最接近待分配内存作业大小的;
缺点:产生大量难以利用的外部碎片。
4.最坏适应算法(Worst Fit)
优点:效率高,分区查找方便;
缺点:当小作业把大空闲分区分小了,那么,大作业就找不到合适的空闲区。
五、代码实现
Partition.h
#pragma once
#include <iostream>
#include <fstream>
#include<string>
#include<vector>
#include<functional>
#include<cstdlib>
#include<map>
#include<set>
using namespace std;
typedef struct//分区
{
static int PartitionNum;//分区数量
int m_PartitionId;//分区首地容量址
int m_PartitionSize;//分区
int m_BlockId;//空白分区首地址
}Partition;
typedef struct//进程控制块
{
static int PCBNum;//进程数量
string m_PidName;//进程名称
int m_PidSize;//进程大小
}PCB;
void ReadData();//读入数据
void Display1();
void Display_Partition();
void Display();//输出分区完后各个分区的状态
void Display_PCB();//显示进程的状态
void FirstFit();//首次适应算法
void NextFit();//循环首次适应算法
void BestFit();//最佳适应算法
void WorstFit();//最坏适应算法
Partition.cpp
#include" Partition.h"
int Partition::PartitionNum = 0;
int PCB::PCBNum = 0;
Partition* partition;
PCB* pcb;
int MIN;
void ReadData()//读入数据
{
ifstream readData;
readData.open("data.txt");
readData >> Partition::PartitionNum;//读入分区数量
partition = new Partition[Partition::PartitionNum];//开空间
for (int i = 0; i < Partition::PartitionNum; i++)//读入分区起始地址
{
readData >> partition[i].m_PartitionId;
partition[i].m_BlockId = partition[i].m_PartitionId;
}
for (int i = 0; i < Partition::PartitionNum; i++)//读入分区大小
{
readData >> partition[i].m_PartitionSize;
}
//readData >> PCB::PCBNum;//读入进程数量
//pcb = new PCB[PCB::PCBNum];
//for (int i = 0; i < PCB::PCBNum; i++)//读入进程名称
//{
// readData >> pcb[i].m_PidName;
//}
//for (int i = 0; i < PCB::PCBNum; i++)//读入进程大小
//{
// readData >> pcb[i].m_PidSize;
//}
//readData.close();
}
void FirstFit()//首次适应算法
{
bool flag = false;
int i, j;
string choose;
ReadData();
//cout << "输入MIN:";
//cin >> MIN;
//Display_PCB();
do
{
Display_Partition();
pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
cout << "输入进程名称:";
cin >> pcb[PCB::PCBNum - 1].m_PidName;
cout << "输入进程大小:";
cin >> pcb[PCB::PCBNum - 1].m_PidSize;
i = PCB::PCBNum - 1;
for (j = 0; j < Partition::PartitionNum; j++)
{
if (pcb[i].m_PidSize <= partition[j].m_PartitionSize)
{
partition[j].m_PartitionSize -= pcb[i].m_PidSize;
partition[j].m_BlockId += partition[j].m_PartitionSize;
if (partition[j].m_PartitionSize <= MIN)
{
partition[j].m_PartitionSize = 0;
}
flag = true;
break;
}
}
if (flag)
{
flag = false;
cout << "进程" << pcb[i].m_PidName << "分配到分区" << partition[j].m_PartitionId << endl;
}
else
{
cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
}
Display1();
cout << "继续分配按Y" << endl;
cin >> choose;
} while (choose == "Y");
}
void NextFit()//循环首次适应算法
{
int pos = 0;
bool flag = false;
int i, j;
string choose;
ReadData();
//Display_PCB();
/*cout << "输入MIN:";
cin >> MIN;*/
do
{
Display_Partition();
pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum+1));
cout << "输入进程名称:";
cin >> pcb[PCB::PCBNum - 1].m_PidName;
cout << "输入进程大小:";
cin >> pcb[PCB::PCBNum - 1].m_PidSize;
i = PCB::PCBNum - 1;
for (j = pos;; j++)
{
if (pos >= PCB::PCBNum)
{
pos = 0;
}
if (pcb[i].m_PidSize <= partition[j].m_PartitionSize)
{
partition[j].m_PartitionSize -= pcb[i].m_PidSize;
partition[j].m_BlockId += partition[j].m_PartitionSize;
if (partition[j].m_PartitionSize <= MIN)
{
partition[j].m_PartitionSize = 0;
}
flag = true;
pos = j + 1;
if (pos == PCB::PCBNum)
{
pos = 0;
}
break;
}
}
if (flag)
{
flag = false;
cout << "进程" << pcb[i].m_PidName << "分配到分区" << partition[j].m_PartitionId << endl;
}
else
{
cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
}
Display1();
cout << "继续分配按Y" << endl;
cin >> choose;
} while (choose == "Y");
}
void BestFit()//最佳适应算法
{
int pos = 0;
bool flag = false;
int i, j;
multimap<int, Partition*> m;
multimap<int, Partition*>::iterator ip;
string choose;
ReadData();
//Display_PCB();
/*cout << "输入MIN:";
cin >> MIN;*/
do
{
Display_Partition();
pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
cout << "输入进程名称:";
cin >> pcb[PCB::PCBNum - 1].m_PidName;
cout << "输入进程大小:";
cin >> pcb[PCB::PCBNum - 1].m_PidSize;
i = PCB::PCBNum - 1;
m.clear();
for (j = 0; j < Partition::PartitionNum; j++)//按从小带大排序
{
m.insert(make_pair(partition[j].m_PartitionSize, partition + j));
}
for (ip = m.begin(); ip != m.end();)
{
if (pcb[i].m_PidSize <= ip->first)
{
ip->second->m_PartitionSize -= pcb[i].m_PidSize;
ip->second->m_BlockId += ip->second->m_PartitionSize;
/*if (ip->second->m_PartitionSize <= MIN)
{
ip->second->m_PartitionSize = 0;
}*/
flag = true;
break;
}
else
{
ip++;
}
}
if (flag)
{
flag = false;
cout << "进程" << pcb[i].m_PidName << "分配到分区" << ip->second->m_PartitionId << endl;
}
else
{
cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
}
Display();
cout << "继续分配按Y" << endl;
cin >> choose;
} while (choose == "Y");
}
void WorstFit()//最坏适应算法
{
int pos = 0;
bool flag = false;
int i, j;
multimap<int, Partition*, greater<int>> m;
multimap<int, Partition*>::iterator ip = m.begin();
string choose;
ReadData();
//Display_PCB();
/*cout << "输入MIN:";
cin >> MIN;*/
do
{
Display_Partition();
pcb = (PCB*)realloc(pcb, sizeof(PCB)*(PCB::PCBNum + 1));
cout << "输入进程名称:";
cin >> pcb[PCB::PCBNum - 1].m_PidName;
cout << "输入进程大小:";
cin >> pcb[PCB::PCBNum - 1].m_PidSize;
i = PCB::PCBNum - 1;
m.clear();
for (j = 0; j < Partition::PartitionNum; j++)//按从大到小排序
{
m.insert(make_pair(partition[j].m_PartitionSize, partition + j));
}
for (ip = m.begin(); ip != m.end();)
{
if (pcb[i].m_PidSize <= ip->first)
{
ip->second->m_PartitionSize -= pcb[i].m_PidSize;
ip->second->m_BlockId += ip->second->m_PartitionSize;
/*if (ip->second->m_PartitionSize <= MIN)
{
ip->second->m_PartitionSize = 0;
}*/
flag = true;
break;
}
else
{
ip++;
}
}
if (flag)
{
flag = false;
cout << "进程" << pcb[i].m_PidName << "分配到分区" << ip->second->m_PartitionId << endl;
}
else
{
cout << "进程" << pcb[i].m_PidName << "分配失败!" << endl;
}
Display();
cout << "继续分配按Y" << endl;
cin >> choose;
} while (choose == "Y");
}
void Display()
{
int i;
set<int> s;
for (i = 0; i < Partition::PartitionNum; i++)
{
s.insert(partition[i].m_PartitionSize);
}
cout << "空白分区链:";
for (auto& e : s)
{
cout << e << "->";
}
cout << "NULL";
cout << endl;
}
void Display1()
{
int i;
map<int, Partition*> m;
for (i = 0; i < Partition::PartitionNum; i++)
{
m.insert(make_pair(partition[i].m_PartitionId, partition + i));
}
cout << "空白分区链:";
for (auto& e : m)
{
if (e.second->m_PartitionSize != 0)
{
cout << e.second->m_PartitionSize << "->";
}
}
cout << "NULL";
cout << endl;
}
void Display_Partition()
{
cout << endl << "分区起始地址 ";
for (int i = 0; i < Partition::PartitionNum; i++)
{
printf("%-d ", partition[i].m_PartitionId);
}
cout << endl << "分区大小: ";
for (int i = 0; i < Partition::PartitionNum; i++)
{
printf("%-d ", partition[i].m_PartitionSize);
}
cout << endl << endl;
}
void Display_PCB()
{
cout << endl << "进程id: ";
for (int i = 0; i < PCB::PCBNum; i++)
{
printf("%3s ", pcb[i].m_PidName.c_str());
}
cout << endl << "进程大小:";
for (int i = 0; i < PCB::PCBNum; i++)
{
printf("%3d ", pcb[i].m_PidSize);
}
cout << endl << endl;
}
Main.cpp
#include"Partition.h"
int main()
{
int choose;
while (1)
{
cout << "请选择实现的算法:" << endl;
cout << "***** 1 - 首次适应算法 *****" << endl;
cout << "***** 2 - 循环首次适应算法 *****" << endl;
cout << "***** 3 - 最佳适应算法 *****" << endl;
cout << "***** 4 - 最坏适应算法 *****" << endl;
cout << "***** 0 - 结束 *****" << endl;
cout << "输入你的选择 : ";
cin >> choose;
switch (choose)
{
case 0:exit(0); break;
case 1:FirstFit(); break;
case 2:NextFit(); break;
case 3:BestFit(); break;
case 4:WorstFit(); break;
default:cout << "请输入正确的序号:" << endl;
}
}
system("pause");
return 0;
}
(488条消息) 动态分区分配算法(First Fit,Next Fit,Best Fit,Worst Fit)_托马斯.杨的博客-CSDN博客_动态分区分配算法