操作系统实验——连续存储管理仿真
一、固定分区存储管理
1.固定分区分配
1.1 原理
将用户空间划分为若干个固定大小的分区,在每个分区中只装入一道作业
1.2 方式
分区大小相等:缺乏灵活性,但是很适合于用一台计算机控制多个相同对象的场合
分区大小不等:增加了灵活性,可以满足不同大小的基础南横需求。根据常在系统中运行的作业大小情况进行划分
1.3 分区使用表
操作系统需要建立一个数据结构—分区说明表。来实现各个分区的分配与回收。每个表对应一个分区,通常按照分区大小排列
每个表包括对应分区的大小、起始地址、状态等,详见2.1
1.4 优点
实现简单,无外部碎片
1.5 缺点
当用户程序太大时,可能所有的分区都不能满足需求,此时不得不采用覆盖技术来解决,但这又会降低性能
会产生内部碎片,内存利用率低
2. 仿真实现
2.1 分区使用表
// Partition description
struct PD
{
int id; // 分区号
int begin; // 起始位置
int size; // 分区大小
bool flag; // 是否分配
int isUseSize; // 已使用大小
PD() {}
PD(int id, int begin, int size)
{
this->id = id;
this->begin = begin;
this->size = size;
flag = false;
isUseSize = 0;
}
};
vector<PD> PDTable;
2.2 分区初始化
// 大 中 小 分区的个数
const int bigPartitionNum = 5;
const int middlePartitionNUm = 20;
const int smallPartitionNum = 10;
// 大 中 小 分区的大小
const int bigPartitionSize = 256;
const int middlePartitionSize = 64;
const int smallPartitionSize = 16;
// 内存起始位置
const int BEGIN = 0;
// 初始化分区使用表
void init()
{
// 分区号
int id = 1;
for (int i = 0; i < smallPartitionNum; i++)
{
PD p(id, BEGIN + i * smallPartitionSize, smallPartitionSize);
PDTable.push_back(p);
id++;
}
int middleBegin = BEGIN + smallPartitionNum * smallPartitionSize;
for (int i = 0; i < middlePartitionNUm; i++)
{
PD p(id, middleBegin + i * middlePartitionSize, middlePartitionSize);
PDTable.push_back(p);
id++;
}
int bigBegin = middleBegin + middlePartitionNUm * middlePartitionSize;
for (int i = 0; i < bigPartitionNum; i++)
{
PD p(id, bigBegin + i * bigPartitionSize, bigPartitionSize);
PDTable.push_back(p);
id++;
}
}
2.3 分配作业
/**
* 分配作业
* 分配成功返回true 分配失败返回false
* 参数:作业ID 作业大小
*/
bool allocate(int id, int size)
{
// 从分区号最低的分区开始遍历 直到找到第一个符合要求的分区
for (int i = 0; i < PDTable.size(); i++)
{
// 如果已经分配则跳过
if (PDTable[i].flag)
continue;
if (PDTable[i].size >= size)
{
PDTable[i].flag = true;
PDTable[i].isUseSize = size;
PDTable[i].workId = id;
return true;
}
}
return false;
}
2.4 统计内部碎片
/**
* 统计内部碎片(memory fragmentation)大小
*/
int getMemoryFragmentationSize()
{
int res = 0;
for (int i = 0; i < PDTable.size(); i++)
{
if (PDTable[i].flag)
{
res += PDTable[i].size - PDTable[i].isUseSize;
}
}
return res;
}
2.5 查看作业分配情况
/**
* 查看作业分配情况
*/
void show()
{
cout << setw(10) << "分区号" << setw(10) << "分区大小" << setw(15) << "分区起始地址" << setw(10) << "分区状态" << setw(15) << "分配作业号" << setw(15) << "内部碎片大小" << endl;
for (int i = 0; i < PDTable.size(); i++)
{
cout << setw(10) << PDTable[i].id;
cout << setw(10) << PDTable[i].size;
cout << setw(15) << PDTable[i].begin;
cout << setw(10) << (PDTable[i].flag == true ? "已分配" : "未分配");
if (PDTable[i].flag)
{
cout << setw(15) << PDTable[i].workId;
cout << setw(15) << PDTable[i].size - PDTable[i].isUseSize;
}
cout << endl;
}
}
2.6 创建测试样例 测试
// 待分配作业
const pair<int, int>
work[] = {{1, 12}, {2, 16}, {3, 20}, {4, 25}, {5, 52}, {6, 64}, {7, 78}, {8, 92}, {9, 156}, {10, 230}, {11, 290}};
int main()
{
// 初始化
init();
// 记录分配成功的情况
int success = 0;
// 分配作业
for (int i = 0; i < 11; i++)
{
success += allocate(work[i].first, work[i].second);
}
// 分配作业情况
show();
cout << "分配成功的作业数:" << success << " 分配失败的作业数:" << 11 - success << endl;
cout << "内部碎片大小:" << getMemoryFragmentationSize() << endl;
}
2.7 结果截图


浙公网安备 33010602011771号