动态分区分配存储管理系统

动态分区分配存储管理系统
动态分区分配存储管理系统

动态分区分配存储管理系统

学院

专业

学号

学生姓名

指导老师

2014年3月19日

目录

一、设计目的与内容 (3)

1、设计目的 (3)

2、设计内容 (3)

3、设计要求 (3)

二、算法的基本思想 (3)

1、首次适应算法 (3)

2、循环首次适应算法 (3)

三、主要功能模块流程图 (4)

1、主函数流程图....................................................................................................................... .4

2、首次适应算法流程图........................................................................................................... .5

3、循环首次适应算法流程图................................................................................................... .6

四、系统测试..................................................................................................................................... .7

输入界面,按要求输入: (7)

五、结论 (8)

六、源程序 (9)

一、设计目的与内容

设计的目的

操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。

●进一步巩固和复习操作系统的基础知识。

●培养学生结构化程序、模块化程序设计的方法和能力。

●提高学生调试程序的技巧和软件设计的能力。

●提高学生分析问题、解决问题以及综合利用C 语言进行程序设计的

能力。

设计内容:

用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法

1.首次适应算法

2.循环首次适应算法

设计要求:

1.内存中有0-100M 的空间为用户程序空间,最开始用户空间是空闲的

2.作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入

3.可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、

进入内存时间、运行时间的初始化

4.根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存

的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、

结束(运行结束,退出内存)三种状态。(为了简化,不考虑CPU 的

调度与切换,运行时间为作业在内存中驻留的时间)

5.能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作,

所有过程均有动态图形变化的显示

6.采用可视化界面,可随时暂停显示当前内存分配和使用情况图。

二、算法的思想

1、首次适应算法

空闲分区链以地址递增的次序链接,分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,取消的空闲分区仍留在空闲链中。若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。

2、循环首次适应算法

在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业

三、主要功能模块流程图

主函数

是 否

f Inputchoice(ch)

Initpartitionlist(p) Ch=1 break Ch=2 multiplex multiplex 结束 开始

Dulinklistp

首次适应算法:

开始 T&&num Dulinklistpll=block... Intx=0 X

Intt=1

循环首次适应算法

四、系统测试

开始 T&&num Dulinklistpll=block... Intm=0 m

Intt=1

程序运行实例如下:

输入界面,按要求输入:

五、结论

作业采用数组形式进行存储,起初想用数组模拟分区,但划分记录比较不易,时间空间复杂度较大,容易混乱,遂决定用链表形式模拟分区情况。基本能运行符合要求,能模拟出动态分区过程及最终结果

六.源程序

#include

#include

#include

#include

#define Free 0

#define Use 1

#define MAX_length 100 //最大内存空间为100MB

#define MaxNumber 100

int FreePartition[MaxNumber]={16,16,8,32,64,32,8,16,64};//空闲分区

int ProcessNeed[MaxNumber]={7,18,9,20,35,8};//每个进程需求

int FirstPartition[MaxNumber];//首次

int CycleFirstPartition[MaxNumber];//循环

int PartitionNumber=9,ProcessNum=6;//空闲分区数及进程数

bool v();

bool v()

{

int j;

cout<<"首次适应算法"<

// FirstPartitionMethod();

for(int i=0;i

for(j=0;j

{

if(FreePartition[j]>=ProcessNeed[i])

{ FirstPartition[i] =j;

FreePartition[j]-=ProcessNeed[i];

break;

}

}

// c_out(FirstPartition);

for(i=0;i

cout<

cout<

// Beginning();

FreePartition[0]=16;

FreePartition[1]=16;

FreePartition[2]=8;

FreePartition[3]=32;

FreePartition[4]=64;

FreePartition[5]=32;

FreePartition[6]=8;

FreePartition[7]=16;

FreePartition[8]=64;

cout<<"循环首次适应算法"<

//CycleFirstPartitionMethod();

j=0;

for(i=0;i

for(;;)//分区

{

if(FreePartition[j]>=ProcessNeed[i])

{ CycleFirstPartition[i]=j;

FreePartition[j]-=ProcessNeed[i];

break;

}

j++;

j=j%PartitionNumber;

}

//c_out(CycleFirstPartition);

for(i=0;i

cout<

cout<

return 1;

}

//--------------作业结构体数组----------------------------

typedef struct JOB

{

int num; //作业号

int size; //作业大小

int ctime; //作业进入时间

int rtime; //作业运行时间

int state; //作业状态

}Job;

typedef struct DuLNode

{

int ID; //分区号

int start; //开始地址

int size; //大小

int state; //0=尚未使用1=使用2=释放

struct DuLNode *prior;//前驱指针

struct DuLNode *next; //后即指针

}DuLNode, * DuLinkList;

//------------------------------------------------------------------------------- int Firstfit(int);//首次适应算法

int Next_fit(int); //循环首次适应算法

void showJob(int); //显示作业表

void showPartiton(DuLinkList);//显示分区表

//-----------------------------------------------------------------------------

//---------------------------全局变量------------------------------------------- int f;

Job *A; //排序前

Job *a; //排序后

Job *temp;

//-----------------------------功能函数------------------------------------------- void delay()

{

for(int x = 10000;x>0;x--)

for(int y = 1000;y>0;y--);

}

//--------------------------------------------------------------------------------

//------------------------初始化--------------------------------------------------- DuLinkList InitpartitionList(DuLinkList &p)

{

p=(DuLinkList)malloc(sizeof(DuLNode));//申请空间

if(!p)

exit(0);

p->size=100; //初始化大小

printf("输入分区首地址:");

scanf("%d",&p->start);

p->state=0; //状态置空闲

p->ID=0; //分区号

p->next=NULL;

p->prior=NULL;

return p;

}

//------------------------------------------------------------------------------

//-----------------------------输入函数--------------------------------------------- int Putin(int &n)

{

int i;

Job temp;

printf("请输入任务数目:");

scanf("%d",&n);

a=(Job*)malloc(n*sizeof(Job));

A=(Job*)malloc(n*sizeof(Job));

for(i=0;i

{

printf("\n");

printf("信息输入:\n\n");

printf("作业号:");

scanf("%d",&a[i].num);

printf("作业大小:");

scanf("%d",&a[i].size);

printf("作业进入时间:");

scanf("%d",&a[i].ctime);

printf("作业运行时间:");

scanf("%d",&a[i].rtime);

a[i].state=0; //默认状态为Free

A[i] = a[i];

}

for(int j = 0;j < n;j++)

for(i = j;i< n;i++)

if(a[j].ctime > a[i].ctime)

{

temp = a[j];

a[j] = a[i];

a[i] = temp;

}

//冒泡排序

freopen("data.txt","w",stdout);

for (i = 0;i < n;i++)

{

printf("%d %d %d %d\n",a[i].num,a[i].size,a[i].ctime,a[i].rtime);

}

fclose(stdout);

freopen("CON","w",stdout);

printf("保存成功\n\n");

return 1;

}

//---------------------------------------------------------------------------------------- //-----------------------------读文件----------------------------------------------------- int order(int &n)

{

Job temp;

printf("Input the number of the task:\n");

scanf("%d",&n);

a=(Job*)malloc(n*sizeof(Job));

freopen("data.txt","r",stdin);

for(int i=0;i

{

scanf("%d",&a[i].num);

scanf("%d",&a[i].size);

scanf("%d",&a[i].ctime);

scanf("%d",&a[i].rtime);

}

fclose(stdin);

freopen("CON","r",stdin);

for(int j = 0;j < n;j++)

for(i = j;i< n;i++)

if(a[j].ctime > a[i].ctime)

{

temp = a[j];

a[j] = a[i];

a[i] = temp;

}

return 1;

}

//------------------------------------------------------------------------

//-------------------------显示分区-------------------------------

void showPartition(DuLinkList pl)

{

printf("\n\t\t\t分区表\n");

printf("\t---------------------------------------\n");

printf("\t 开始地址\t分区号\t大小状态\n");

printf("\t---------------------------------------\n");

while(pl)

{

printf("\t %d\t\t%d\t%d\t",pl->start,pl->ID,pl->size);

if(pl->state == 0)

printf("空闲\n");

if(pl->state == 1)

printf("已分配\n");

pl=pl->next;

}

printf("\t---------------------------------------\n");

}

//-------------------------------------------------------------------------

//---------------------------------回收函数---------------------------------

void huishou(DuLinkList pl3,DuLinkList &pl)//pl3是分区链表指针pl头

{

while(pl3)

{

if(pl3->state==0)

{

if(pl3->next&&pl3->prior&&pl3->prior->state==0&&pl3->next->state==1)//

{

pl3->size+=pl3->prior->size;

pl3->start=pl3->prior->start;

pl3->state=0;

pl3->ID=0;

if(pl3->prior->prior)

{

pl3->prior->prior->next=pl3;//pl3与最前一个

pl3->prior=pl3->prior->prior;//

}

else

{

pl3->prior=pl3->prior->prior;//pl3指向空

pl=pl3;

pl3=pl;//pl3与头

}

}

else if(pl3->prior&&pl3->next&&pl3->next->state==0&&pl3->prior->state==1) {

pl3->size+=pl3->next->size;

pl3->state=0;

pl3->ID=0;

if(pl3->next->next)

{

pl3->next->next->prior=pl3;//建立新链表pl3与最后一个结点

pl3->next=pl3->next->next;//

}

else

{

pl3->next=pl3->next->next;//指向空

}

}

else if(!pl3->prior)

{

if(pl3->next->state==0)

{

pl3->size+=pl3->next->size;

pl3->state=0;

pl3->ID=0;

if(pl3->next->next)

pl3->next->next->prior=pl3;//pl3与最后

pl3->next=pl3->next->next;//

}

else

{

pl3->state=0;

}

}

else if(!pl3->next)

{

if(pl3->prior->state==0)

{

pl3->size+=pl3->prior->size;

pl3->state=0;

pl3->ID=0;

pl3->start=pl->start;

if(pl3->prior->prior)

{

pl3->prior->prior->next=pl3;//pl3与最前

pl3->prior=pl3->prior->prior;//

}

else

{ pl3->prior=NULL;//pl3指向空

pl=pl3;//pl3与头

pl3=pl;//

}

}

else

{

pl3->state=0;

}

}

else if(pl3->next&&pl3->prior&&pl3->next->state==0&&pl3->prior->state==0) {

pl3->size=pl3->size+pl3->next->size+pl3->prior->size;

pl3->state=0;

pl3->ID=0;

pl3->start=pl3->prior->start;

if(pl3->next->next)

pl3->next->next->prior=pl3;

if(pl3->prior->prior)

{

pl3->prior->prior->next=pl3;

pl3->next=pl3->next->next;//指向空

pl3->prior=pl3->prior->prior;

}

else

{

pl3->next=pl3->next->next;//指向空

pl3->prior=pl3->prior->prior;//指向头

pl=pl3;

pl3=pl;

}

}

}

pl3=pl3->next;

}

}

//--------------------------------------------------------------------------------------

//----------------------------------首次适应算法---------------------------------------

void Firstfit(DuLinkList block_first,int n)

{

int t=1;

int num=n;

while(t&&num)

{

DuLinkList pl1=block_first,pl2,pl3=block_first;

printf("时钟:%d\n",t);

DuLNode *p=block_first;

DuLNode *q=block_first;

for(int x=0;x

{ if(t==a[x].ctime+a[x].rtime)

a[x].state=2;

}

for(int m=0;m

{

if(t==a[m].ctime+a[m].rtime)

{

num-=1;

a[m].state=2;//0 等待1 装入2结束

while(q)

{

if(q->ID==a[m].num)//分区号等于作业号时

{

q->state=Free;//在作业完成时,作业号等于分区号时空闲

}

q=q->next;

}

showJob(n);

showPartition(block_first);

}

}

for( m=0;m

{

if(a[m].ctime==t)

{

a[m].state=1;

printf("作业:%d开始运行,对其分配!",a[m].num);

}

for( m=0;m

{

if(t==a[m].ctime)

{

while(pl1&&(pl1->state == 1||pl1->sizenext;

if(pl1)

{

pl2=(DuLinkList)malloc(sizeof(DuLNode));

pl2->start=pl1->start+a[m].size;

pl2->state=0;

pl2->ID=0;

pl2->size=pl1->size-a[m].size;

if(pl2->size>5)

{

pl1->size=a[m].size;

pl1->state=1;

pl1->ID=a[m].num;

if(pl1->next)

pl1->next->prior=pl2;

pl2->next=pl1->next;

pl2->prior=pl1;

pl1->next=pl2;

pl1=block_first;

}

else

{

pl1->state=1;

pl1->ID=a[m].num;

}

showJob(n);

showPartition(block_first);

}

else

{

cout<<"内存不足,等待释放"<

for(int i=m;i

{

a[i].ctime+=1;

}

p=block_first;

huishou(p, block_first);

}

}

t+=1;

}

}

//---------------------------------------------------------------

//---------------------------显示作业----------------------------

void showJob(int n)

{

printf("\n\t\t\t作业表:\n");

printf("\t--------------------------------------------------------------\n");

printf("\t 作业号\t大小\t进入时间\t运行时间\t状态\n");

printf("\t--------------------------------------------------------------\n");

for(int m=0;m

{

printf("\t %d\t %d\t%d\t %d\t",a[m].num,a[m].size,a[m].ctime,a[m].rtime);

if(a[m].state == 0)

printf(" 等待\n");

if(a[m].state == 1)

printf(" 装入\n");

if(a[m].state == 2)

printf(" 结束\n");

}

printf("\t--------------------------------------------------------------\n");

}

//---------------------------------------------------------------------

//-------------------- 循环首次适应算法------------------------

void Nextfit(DuLinkList block_first,int n)

{

int t=1;

int num=n;

DuLinkList flag;

flag=block_first;

while(t&&num)

{

DuLinkList pl1=block_first,pl2,pl3=block_first;

printf("时钟:%d\n",t);

DuLNode *p=block_first;

DuLNode *q=block_first;

for(int m=0;m

{

if(t==a[m].ctime+a[m].rtime)

{

num-=1;

a[m].state=2;

while(q)

{

if(q->ID==a[m].num)

{

q->state=Free;

}

q=q->next;

}

showJob(n);

showPartition(block_first);

}

}

for( m=0;m

{

if(a[m].ctime==t)

{

a[m].state=1;

printf("作业:%d开始运行,对其分配!",a[m].num);

}

}

for( m=0;m

{

if(t==a[m].ctime)

{

while(flag&&(flag->state == 1||flag->sizenext;

pl1=flag;

if(pl1)

{

pl2=(DuLinkList)malloc(sizeof(DuLNode));

pl2->start=pl1->start+a[m].size;

pl2->state=0;

pl2->ID=0;

pl2->size=pl1->size-a[m].size;

if(pl2->size>5)

{

pl1->size=a[m].size;

pl1->state=1;

pl1->ID=a[m].num;

if(pl1->next)

pl1->next->prior=pl2;

实验三动态分区存储管理方式的主

实验三动态分区存储管理方式的主存分配回收 一、实验目的 深入了解动态分区存储管理方式主存分配回收的实现。 二、实验预备知识 存储管理中动态分区的管理方式。 三、实验内容 编写程序完成动态分区存储管理方式的主存分配回收的实现。实验具体包括: 首先确定主存空间分配表;然后采用最优适应算法完成主存空间的分配和回收;最后编写主函数对所做工作进行测试。 四、提示与讲解 动态分区管理方式预先不将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。当作业要求装入主存时,根据作业需要主存空间的大小查询主存内各个空闲区,当从主存空间中找到一个大于或等于该作业大小的主存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装入该作业。作业执行完后,它所占的主存分区被收回,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 实现动态分区的分配和回收,主要考虑的问题有三个: 第一,设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计主存分配算法;第三,在设计的数据表格基础上设计主存回收算法。 首先,考虑第一个问题: 设计记录主存使用情况的数据表格,用来记录空闲区和作业占用的区域。 由于动态分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在主

存中的起始地址和长度。由于分配时空闲区有时会变成两个分区: 空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一张表格记录已分分区和空闲区,就会使表格操作繁琐。主存分配时查找空闲区进行分配,然后填写已分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。 由此可见,主存的分配和回收主要是对空闲区的操作。这样为了便于对主存空间的分配和回收,就建立两张分区表记录主存使用情况,一张表格记录作业占用分区的 “已分配区表”;一张是记录空闲区的“空闲区表”。这两张表的实现方法一般有两种,一种是链表形式,一种是顺序表形式。在实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分配区表”还是“空闲区 表”都必须事先确定长度。它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因而在多数情况下,无论是“已分配区表”还是“空闲区表”都有空闲栏目。已分配区表中除了分区起始地址、长度外,也至少还要有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个作业占用分区的登记项,内容为该作业的作业名;空闲区表中除了分区起始地址、长度外,也要有一项“标志”,如果是空闲栏目,内容为“空”,如果为某个空闲区的登记项,内容为“未分配”。在实际系统中,这两表格的内容可能还要多,实验中仅仅使用上述必须的数据。为此, “已分配区表”和“空闲区表”在实验中有如下的结构定义。 已分配区表的定义: #define n 10// 假定系统允许的最大作业数量为n struct {float address;// 已分分区起始地址 float length; // 已分分区长度,单位为字节 int flag;// 已分配区表登记栏标志, “0表”示空栏目,实验中只支持一个字符的作业名}used_table[n];// 已分配区表 空闲区表的定义:

实验五 动态分区存储管理

实验五动态分区存储管理 一、实验目的 深入了解采用动态分区存储管理方式的内存分配回收的实现。通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉动态分区存储管理的内存分配和回收。 二、实验内容 编写程序完成动态分区存储管理方式的内存分配回收。 具体包括:确定内存空间分配表; 采用最优适应算法完成内存空间的分配和回收; 编写主函数对所做工作进行测试。 三、设计思路 整体思路: 动态分区管理方式将内存除操作系统占用区域外的空间看成一个大的空闲区。当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 设计所采用的算法: 采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业。但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率。为解决此问题,设定一个限值minsize,如果空闲区的大小减去作业需求长度得到的值小于等于minsize,不再将空闲区分成己分分区和空闲区两部分,而是将整个空闲区都分配给作业。 内存分配与回收所使用的结构体: 为便于对内存的分配和回收,建立两张表记录内存的使用情况。一张为记录作业占用分 区的“内存分配表”,内容包括分区起始地址、长度、作业名/标志(为0时作为标志位表示空栏目);一张为记录空闲区的“空闲分区表”,内容包括分区起始地址、长度、标志(0表空栏目,1表未分配)。两张表都采用顺序表形式。

动态分区式存储管理

可变分区存储管理 设计思路: 整体思路: 可变分区管理方式将内存除操作系统占用区域外的空间看做一个大的空闲区。当作业要求装入内存时,根据作业需要内存空间的大小查询内存中的各个 空闲区,当从内存空间中找到一个大于或等于该作业大小的内存空闲区时,选择其中一个空闲区,按作业需求量划出一个分区装人该作业,作业执行完后,其所占的内存分区被收回,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 设计所才用的算法: 采用最优适应算法,每次为作业分配内存时,总是把既能满足要求、又是最小的空闲分区分配给作业。但最优适应算法容易出现找到的一个分区可能只比作业所需求的长度略大一点的情行,这时,空闲区分割后剩下的空闲区就很小以致很难再使用,降低了内存的使用率。为解决此问题,设定一个限值min size,如果空闲区的大小减去作业需求长度得到的值小于等于min size,不再将空闲区分成己分分区和空闲区两部分,而是将整个空闲区都分配给作业。 内存分配与回收所使用的结构体: 为便于对内存的分配和回收,建立两张表记录内存的使用情况。一张为记录作业占用分区的“内存分配表”,内容包括分区起始地址、长度、作业名/标志(为0时作为标志位表示空栏目);一张为记录空闲区的“空闲分区表”,内容包括分区起始地址、长度、标志(0表空栏目,1表未分配)。两张表都采用顺序表形式。 关于分配留下的内存小碎片问题: 当要装入一个作业时,从“空闲分区表”中查找标志为“ 1”(未分配)且满足作业所需内存大小的最小空闲区,若空闲区的大小与作业所需大小的差值小于或等于min size,把该分区全部分配给作业,并把该空闲区的标志改为“0”(空栏目)。同时,在已分配区表中找到一个标志为“ 0”的栏目登记新装人作业所占用分区的起始地址,长度和作业名。若空闲区的大小与作业所需大小的差值大于

实验五动态分区存储管理模拟

实验五动态分区存储管理模拟 一、实验目的 深入了解可变分区存储管理式主存分配回收的实现。 二、实验预备知识 可变分区存储管理式不预先将主存划分成几个区域,而把主存除操作系统占用区域外的空间看作一个大的空闲区。当进程要求装入主存时,根据进程需要主存空间的大小查询主存各个空闲区,当从主存空间找到一个大于或等于该进程大小要求的主存空闲区时,选择其中一个空闲区,按进程需求量划出一个分区装入该进程。进程执行完后,它所占的主存分区被回收,成为一个空闲区。如果该空闲区的相邻分区也是空闲区,则需要将相邻空闲区合并成一个空闲区。 这个实验主要需要考虑三个问题: (1)设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域; (2)在设计的数据表格基础上设计主存分配算法; (3)在设计的数据表格基础上设计主存回收算法。 首先,考虑第一个问题:设计记录主存使用情况的数据表格,用来记录空闲区和进程占用的区域。 由于可变分区的大小是由进程需求量决定的,故分区的长度是预先不固定的,且分区的个数也随主存分配和回收而变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在主存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收主存分区时,可能会合并空闲分区,这样如果整个主存采用一表格记录已分分区和空闲区,就会使表格操作繁琐。主存分配

时查找空闲区进行分配,然后填写已分分区表,主要操作在空闲区;某个进程执行完成后,将该分区变成空闲区,并将其与相邻空闲区合并,主要操作也在空闲区。由此可见,主存分配和回收主要是对空闲区的操作。 这样,为了便于对主存空间的分配和回收,就建立两分区表记录主存使用情况,一表格记录进程占用分区的“已分分区表”;一是记录空闲区的“空闲区表”。这两表的实现法一般有两种,一种是链表形式,一种是顺序表形式。在实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。它们的长度必须是系统可能的最大项数,系统运行过程中才不会出错,因而在多数情况下,无论是“已分分区表”还是“空闲区表”都有空闲栏目。已分分区表中除了分区起始地址、长度外,也至少还要有一项“标志”,如果是空闲栏目,容为“空”,如果为某个进程占用分区的登记项,容为该进程的进程名;空闲区表中除了分区起始地址、长度外,也要有一项“标志”,如果是空闲栏目,容为“空”,如果为某个空闲区的登记项,容为“未分配”。在实际系统中,这两个表格的容可能还要更多,实验中仅仅使用上述必须的数据。为此,“已分分区表”和“空闲区表”在实验中有如下的结构定义: 已分分区表的定义: #define n 10 //假定系统允的进程数量最多为n struct { float address; //已分分区起始地址 float length; //已分分区长度,单位为字节

固定分区存储管理

理工大学信息工程与自动化学院学生实验报告 ( 2013 —2014 学年第一学期) 课程名称:操作系统开课实验室:信自楼444 2013年 11月28 日 注:报告容按下列的要求进行。 一、实验目的 通过编写固定分区存储管理的模拟程序,加深对操作系统存储管理功能中的固定分区管理方式、主存分配表等相应知识的理解。 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的存分配和回收。 二、实验题目 1.设计一个固定分区分配的存储管理方案。并模拟实现分区的分配和回收过程。 2.必须建立分区表,记录空闲区与占用区的状况。

本系统将存用户空间划分为五个大小不固定的分区,其分区大小由用户输入决定。在每个分区只装入一道作业,这样把用户空间划分为几个分区,便允许几道作业并发运行。当有一个空闲分区时,便可以从外存的后备队列中选择一个适当大小的作业装入该分区,当该作业结束时又可以从后备作业队列中找出另一作业调入该分区。 每个存空间是一个Node型的对象。Node类有一个三个参数的构造函数。分别为:分区号、起始地址、大小。然后就是一些属性的get、set方法和一个打印其属性的函数。四个数据域分别为:属性m_No用来表示该存空间的序号。属性m_Addr用来表示存分区的起始地址。属性m_Size用来表示存空间的大小。属性m_State表示存空间的是否已分配的状态标志。若该存空间已分配,m_TaskNo表示占有该存空间的任务序号。否则没有实际意义。 在用户申请任务的存空间时,提示用户输入任务号和其需要的存空间大小。 流程图 主程序:

释放存空间算法

动态分区存储管理系统分解

操作系统原理 课程设计报告 题目:动态分区分配存储管理系统 所在学院:计算机科学与技术学院 班级: 11级计算机科学与技术(非师) 学号: 20111202052 姓名:吴创连 指导教师:黄侠剑 2014年3月18

目录 1 引言 (1) 2 需求分析 (1) 3 概要设计 (1) 4 详细设计 (1) 4.1问题描述和分析 (1) 4.2程序流程图 (2) 4.3数据结构体分析 (3) 4.4主要程序代码分析 (4) 5 调试与操作说明 (11) 5.1初始界面 (11) 5.2模拟内存分配 (12) 5.3回收内存界面 (12) 5.4最佳适应算法的实现 (13) 5.5最坏适应算法的实现 (13) 6总结与体会 (13)

1 引言 操作系统是最重要的系统软件,同时也是最活跃的学科之一。我们通过操作系统可以理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。 存储器是计算机系统的重要组成部分,近年来,存储器容量虽然一直在不断扩大,但仍不能满足现代软件发展的需要,因此,存储器仍然是一种宝贵而又紧俏的资源。如何对它加以有效的管理,不仅直接影响到存储器的利用率,而且还对系统性能有重大影响。而动态分区分配属于连续分配的一种方式,它至今仍在内存分配方式中占有一席之地。 2 需求分析 动态分区分配是根据进程的实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用的数据结构、分区分配算法和分区的分配和回收操作这样三个问题。常用的数据结构有动态分区表和动态分区链。在对数据结构有一定掌握程度的情况下设计合理的数据结构来描述存储空间,实现分区存储管理的内存分配功能,应该选择最合适的适应算法(最佳适应算法,最坏适应算法),在动态分区存储管理方式中主要实现内存分配和内存回收算法,在这些存储管理中间必然会有碎片的产生,当碎片产生时,进行碎片的拼接等相关的内容。 3 概要设计 本程序采用机构化模块化的设计方法,共分为两大模块。 1.最佳适应算法实现 它从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求的自由分区分配。 2.最坏算法实现 最坏适应分配算法要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。该算法要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。 4 详细设计 4.1 问题描述和分析 系统应利用某种分配算法,从空闲分区链表中找到所需大小的分区,如果空闲分区大小

动态分区存储管理的模拟实现

计算机科学与工程学院学生实验报告 专业计算机科学与技术班级 学号姓名 课程名称操作系统课程类型专业必修课 实验名称动态分区存储管理的模拟实现 实验目的: 1.熟悉动态分区存储管理方式下,主存空间的分配和回收算法。 2.提高C语言编程能力。 实验内容: 假设主存当前状态如右表所示: 系统采用最佳适应分配算法为作业分配主存空间, 而且具有紧凑技术。请编程完成以下操作: (1). 输出此时的已分配区表和未分配区表; (2). 装入 Job3(15K),输出主存分配后的已分配 区表和未分配区表; (3). 回收 Job2所占用的主存空间,输出主存回收 后的已分配区表和未分配区表; (4).装入 Job4(130K),输出主存分配后的已分配 区表和未分配区表。 实验要求 1.数据结构参考定义如下,也可根据需要进行改进: (1)已分配区表: #define n 10 /*假定系统允许的最大作业数量为n,n值为10*/ struct {int number; /*序号*/ int address; /*已分配分区起始地址,单位为KB */ int length; /*已分配分区长度,单位KB*/ float flag; /*已分配区表登记栏标志,0:空表项,否则为作业名;*/

}used_table[n]; /*已分配区表*/ (2)未分配区表: #define m 10 /*假定系统允许的空闲区表最大为m,m值为10*/ struct {int number; /*序号*/ int address; /*空闲区起始地址,单位为KB */ int length; /*空闲区长度,单位为KB*/ int flag; /*空闲区表登记栏标志,0:空表项;1:空闲区*/ }free_table[m]; /*空闲区表*/ 2.以allocate命名主存分配所用的过程或函数(算法参考课件),要将各种情况考虑周全。 3.以reclaim命名主存回收所用的过程或函数(算法参考课件),要将各种情况考虑周全。 4.画出算法实现的N-S流程图。 5.程序调试、运行成功后,请老师检查。 实验步骤: 1.分配内存,结果如下图:

动态分区分配管理系统

动态分区分配管理系统 学院 专业 学号 学生姓名 指导教师姓名 2014年3月14 日

目录 1程序设计的内容和相关的要求---------------------------------2 2程序总的功能说明--------------------------------------------3 3程序的模块的说明--------------------------------------------4 4程序设计的流程图--------------------------------------------5 5程序的操作说明及运行结果-----------------------------------7 6源程序-------------------------------------------------------11 7心得体会----------------------------------------------------27

1程序设计的内容和相关的要求: 课程设计的目的:操作系统课程设计是计算机学院重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决实际问题的机会。 ● 进一步巩固和复习操作系统的基础知识。 ● 培养学生结构化程序、模块化程序设计的方法和能力。 ● 提高学生调试程序的技巧和软件设计的能力。 ● 提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能 力。 实现的任务:编写一个动态分区分配程序。 设计内容: 用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算法 1.首次适应算法 2.循环首次适应算法 设计要求: 1.内存中有0-100M的空间为用户程序空间,最开始用户空间是空闲的; 2.作业数量、作业大小、进入内存空间、运行时间需要通过界面进行输入; 3.可读取样例数据(要求存放在外部文件夹中)进行作业数量、作业大小、进图内存时间、运行时间的初始化; 4.根据作业进图内存的时间,采用简单的先进先出原则进行从外村到内存的调度,作业具有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。(为了简化,不考虑cpu的调度与切换,运行时间为作业在内存中驻留的时间); 5.能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作,所有过程均有动态图形变化的显示; 6.采用可视化界面,可随时暂停显示当前内存分配和使用情况图。 2程序总的功能说明: 本程序可以从界面直接输入作业并进行动态的内存分配,也可以自动地生成作业文件并自行调度进行内存分配,每次分配可以选择两种算法(首次适应算法和循环首次算法)中的一种,每次作业结束后可以进入操作主界面进行再次作业的操作。 首次适应算法(First-fit):当要分配内存空间时,就查表,在各空闲区中查找满足大小要求的可用块。只要找到第一个足以满足要球的空闲块就停止查找,并把它分配出去;

存储管理练习题一(带答案)

存储管理练习题一 一、单项选择题 1.采用可重入程序是通过使用()的法来改善响应时间的。 A 减少用户数目 B 改变时间片长短 C 加快对换速度 D 减少对换信息量 (D可重入程序是指该程序被某进程调用,但还未结束,又被另一个进程调用。 可重入程序是通过减少对换信息量来改善系统响应时间的。 可重入程序主要通过共享来使用同一块存储空间的,或者通过动态的式将所需的程序段映射到相关进程中去,其最大的优点是减少了对程序段的调入调出。由此来减少对换信息量。 ) 2.段式存储管理中,用于记录作业分段在主存中的起始地址和长度的是() A 基址寄存器和很长寄存器 B 段表 C 界限寄存器 D 上、下限寄存器 答案:B 3.固定分区存储管理中,CPU在执行作业的指令时,均会核对不等式()是否成立,若不成立,则产生地址越界中断事件,中止该指令的执行。 A 界限寄存器≤绝对地址≤最址 B 下限地址≤绝对地址<上限地址 C 基址寄存器容≤绝对地址≤限长寄存器容 D基址寄存器容<绝对地址<限长寄存器容 答案:B 固定分区存储管理(适合多道程序设计) 1.分区的定义 固定分区存储管理是把主存储器中可分配的用户区域预先划分成若干个连续区,每一个连续区称为一个分区。 2.固定分区存储管理的特点 (1)分区大小固定

(2)分区数目固定。 3.主存空间的分配与回收 存储管理设置“分区分配表”来说明各分区的分配和使用情况。表中指出各分区的起始地址和长度,并为每个分区设置一个标志位。标志位为“0”表示分区空间,非“0”表示分区已被占用。当有作业要装入分区,存储管理分配主存区域时,根据作业地址空间的长度与标志为“0”的分区的长度比较,当有分区长度能容纳该作业时,则把作业装入该分区,且把作业名填到占用标志位上。否则,该作业暂时不能装入。作业运行结束后,根据作业名查分区分配表,把该分区的占用标志置成“0”以示空闲。 4.地址转换和存储保护 因作业存放区域不会改变,可采用静态重定位式把作业装入所在的分区号,且把该分区的下限地址和上限地址分别送入下限寄存器和上限寄存器中。处理器执行该作业的指令时必须核对:“下限地址≤绝对地址≤上限地址”如此等式不成立,产生“地址越界”中断事件。 5.为了提高主存空间的利用率,可以采用如下几种措施: (1)根据经常出现的作业的大小和数量来划分分区,尽可能使各个分区被充分利用。 (2)划分分区时按分区的大小顺序排列,低地址部分是较小的分区,高地址部分是较大的分区。 (3)按作业对主存空间的需求量排成多个作业队列,每个作业队列中的各作业依次装入一个一个固定的分区中,每次装一个作业;不同作业队列中的作业分别依次装入不同的分区中;不同的分区中可同时装入作业;某作业队列为空时;

动态分区分配存储管理系统

动态分区分配存储管理系统 学院 专业 学号 学生姓名 指导老师 2014年3月19日

目录 一、设计目的与内容 (3) 1、设计目的 (3) 2、设计内容 (3) 3、设计要求 (3) 二、算法的基本思想 (3) 1、首次适应算法 (3) 2、循环首次适应算法 (3) 三、主要功能模块流程图 (4) 1、主函数流程图....................................................................................................................... .4 2、首次适应算法流程图........................................................................................................... .5 3、循环首次适应算法流程图................................................................................................... .6 四、系统测试..................................................................................................................................... .7 输入界面,按要求输入: (7) 五、结论 (8) 六、源程序 (9)

固定分区存储管理

昆明理工大学信息工程与自动化学院学生实验报告 ( 2013 —2014 学年第一学期) 课程名称:操作系统开课实验室:信自楼444 2013年 11月28 日 注:报告内容按下列的要求进行。 一、实验目的 通过编写固定分区存储管理的模拟程序,加深对操作系统存储管理功能中的固定分区管理方式、主存分配表等相应知识的理解。 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。 二、实验题目 1.设计一个固定分区分配的存储管理方案。并模拟实现分区的分配和回收过程。 2.必须建立分区表,记录空闲区与占用区的状况。 3.流程图按选定的算法自己完成。

三、算法设计的思想或流程图 本系统将内存用户空间划分为五个大小不固定的分区,其分区大小由用户输入决定。在每个分区只装入一道作业,这样把用户空间划分为几个分区,便允许几道作业并发运行。当有一个空闲分区时,便可以从外存的后备队列中选择一个适当大小的作业装入该分区,当该作业结束时又可以从后备作业队列中找出另一作业调入该分区。 每个内存空间是一个Node型的对象。Node类有一个三个参数的构造函数。分别为:分区号、起始地址、大小。然后就是一些属性的get、set方法和一个打印其属性的函数。四个数据域分别为:属性m_No用来表示该内存空间的序号。属性m_Addr用来表示内存分区的起始地址。属性m_Size用来表示内存空间的大小。属性m_State表示内存空间的是否已分配的状态标志。若该内存空间已分配,m_TaskNo表示占有该内存空间的任务序号。否则没有实际意义。 在用户申请任务的内存空间时,提示用户输入任务号和其需要的内存空间大小。 流程图 主程序:

动态分区存储管理

《操作系统》课程实验报告实验名称:动态分区存储管理 姓名: 学号: 地点: 指导老师: 专业班级:

一、实验目的: 1、熟悉并掌握动态分区分配的算法。 2、熟悉并掌握动态分区中分区回收的各种情况,并能够实现分区合并。 二、实验内容:用高级语言模拟实现动态分区存储管理,要求: 1、分区分配算法至少实现首次适应算法、最佳适应算法和最坏适 应算法中的至少一种。熟悉并掌握各种算法的空闲区组织方式。 2、分区的初始化——可以由用户输入初始分区的大小。(初始化后 只有一个空闲分区,起始地址为0,大小是用户输入的大小) 3、分区的动态分配过程:由用户输入作业号和作业的大小,实现 分区过程。 4、分区的回收:用户输入作业号,实现分区回收,同时,分区的 合并要体现出来。(注意:不存在的作业号要给出错误提示!) 5、分区的显示:任何时刻,可以查看当前内存的情况(起始地址 是什么,大小多大的分区时空闲的,或者占用的,能够显示出 来) 6、要求考虑:(1)内存空间不足的情况,要有相应的显示; (2)作业不能同名,但是删除后可以再用这个名字; (3)作业空间回收是输入作业名,回收相应的空间,如果这个作业名不存在,也要有相应的提示。 三、实验代码 #include #include #define SIZE 800 // 内存初始大小 #define MINSIZE 5 // 碎片最小值 enum STATE { Free, Busy }; struct subAreaNode { int addr; // 起始地址 int size; // 分区大小 int taskId; // 作业号 STATE state; // 分区状态 subAreaNode *pre; // 分区前向指针 subAreaNode *nxt; // 分区后向指针 }subHead; // 初始化空闲分区链 void intSubArea() { // 分配初始分区内存

操作系统课程设计动态分区分配存储管理

操作系统课程设计 动态分区分配存储管理 吕 霆 计算机10-01班 设计题目 学 号 专业班级 学生姓名 指导教师

第一章课程设计概述 1.1 设计任务: 动态分区分配存储管理 1.2 设计要求 建立描述内存分配状况的数据结构; 建立描述进程的数据结构; 使用两种方式产生进程:(a)自动产生,(b)手工输入; 在屏幕上显示内存的分配状况、每个进程的执行情况; 建立分区的分配与回收算法,支持紧凑算法; 时间的流逝可用下面几种方法模拟:(a)按键盘,每按一次可认为过一个时间单位; (b) 响应WM_TIMER; 将一批进程的执行情况存入磁盘文件,以后可以读出并重放; 支持算法:首次适应算法、循环首次适应算法、最佳适应算法:最坏适应算法。1.3 设计目的 旨在让我们更好的了解动态分区管理方面的知识. 第二章原理及算法描述 2.1动态分区分配算法原理 首次适应算法 * 算法概述:分配内存时,从链首开始顺序查找,找到满足的空闲分区则划出空间分配,余下的空闲空间仍保留在空闲链表中 * 实现方法:分配时从数组第一个元素开始比较,若符合条件则将该元素减去对应作业的值 循环首次适应算法 * 算法概述:由首次适应算法演变,只是每次分配改为由上一次找到的空闲分区开始查找 * 实现方法:在首次适应算法的基础上增加一个值用于记录找到的空闲分区的位置 最佳适应算法 * 算法概述:每次为作业分配内存时,总是把能满足要求、又是最小的空闲分区

分配给作业 * 实现方法:我们决定每次分配先把空闲分区按从小到大的顺序排列,然后将第一个匹配分区分配给作业 最坏适应算法 * 算法概述:每次为作业分配内存时,总是挑选一个最大的空闲分区分割给作业使用 * 实现方法:算法与最佳适应算法几乎相同,仅在排序时把空闲分区表按从大到小的顺序排列,所以未作详细注释 回收分区 当进程运行完毕释放内存时,系统根据回收区的首址,从空闲区链(表)中找到相应的插入点,此时可能出现以下四种情况之一; 1)回收区与插入点的前一个空闲分区F1相邻接,此时应将回收区与插入点的前一分 区合并,不必为回收区分配新表项,而只需修改其前一分区F1的大小. 2)回收分区与插入点的后一空闲分区F2相邻接,此时也可将两分区合并,形成新的 空闲分区,但用回收区的首址作为新空闲区的首址,大小为两者之和. 3)回收区同时与插入点的前,后两个分区邻接,此时将三个分区合并,使用F1的表项 和F1的首址,取消F2的表项,大小为三者之和. 4)回收区既不与F1相邻接,又不与F2邻接.这时应为回收区单独建立一新表项,填 写回收区的首址和大小,并根据其首址插入到空闲链中的适当位置. 紧凑算法 通过移动内存中的作业的位置,以把原来多个分散的小分区拼接成一个大分区的方法. 第三章开发环境 此程序是本人利用c++语言在vs2012的开发环境中实现的 第四章程序实现--数据结构 #include #include #include using namespace std; ofstream stream;//输出流对象 int ary1[20][4];//内存分配状态 int ary2[20][3];//空闲分区状态 int ary3[10];//进程分配状态

第3章存储管理同步练习及答案

第3章存储管理 一、单项选择题 1.为避免主存中各种作业相互干扰,必须进行() A 重定位 B 地址映射 C 地址转换 D 存储保护 2.固定分区存储管理中,CPU在执行作业的指令时,均为核对不等式()是否成立,若不成立,则产生地址越界中断事件,终止该指令的执行。 A 界限地址≤绝对地址≤最大地址 B 下限地址≤绝对地址<上限地址 C 基址寄存器内容≤绝对地址≤限长寄存器内容 D 基址寄存器内容<绝对地址≤限长寄存器内容 3.在请求分页系统中,LRU算法是指()。 A 最早进入内存的页先淘汰 B 近期最长时间以来没被访问的页先淘汰 C 近期被访问次数最少的页先淘汰 D 以后再也不用的页面先淘汰 4.虚拟存储器是()。 A 可以提高计算机运算速度的设备 B 容量扩大了主存的实际空间 C 通过SPOOLING技术实现的 D 可以容纳和超出主存容量的多个作业同时运行的一个地址空间 5.下列存储管理方式中,相比而言,碎片最少,而且主存利用率最高的是()。 A 固定分区 B 可变分区 C 单用户连续存储管理 D 页式 6.采用可变分区存储管理主存时,使用移动技术可以()。 A 加快作业执行速度 B 集中分散的空闲区 C 扩大主存容量 D 加快地址转换 7.在一个请求页式存储管理中,一个程序的页面走向为4,3,2,1,4,3,5,4,3,2,1,5,并且采用LRU算法。设分配给程序的存储块数M分别为3和4,在访问总发生的缺页次数F为()。 A M=3,F=8;M=4,F=5 B M=3,F=10;M=4,F=8 C M=3,F=9;M=4,F=10 D M=3,F=7;M=4,F=6 8.单道系统中经常采用的存储管理方式是()存储管理。 A 固定分区 B 单用户连续 C 可变分区 D 页式 9.请求页式管理中,缺页中断率与进程所分得的内存页面数、()和进程页面流的走向等因素有关。 A 页表的地址 B 置换算法 C 外存管理算法 D 进程调度算法 10.下列存储管理方式中,一般采用静态重定位方式进行逻辑地址到物理地址转换的是()。 A 固定分区 B 段页式 C 可变分区 D 页式 11.下列管理方式中,能实现虚拟存储器的是()。 A 单用户连续方式 B 页式存储管理 C 固定分区D可变分区 12.所谓LFU页面置换算法,是指()。 A 驻留在内存中的页面随便挑选一页淘汰 B 将驻留在内存中时间最长的页页淘汰 C 将驻留在内存中最近最久未使用的一页淘汰 D 将驻留在内存中最近最不经常用的一页淘汰 13.页式存储管理中,每当CPU形成一个有效的地址时,则要查找页面。这一工作是由()实现的。 A 查表程序 B 存取控制 C 硬件自动 D 软件自动 14.设基址寄存器的内容为1000,在采用动态重定位的系统中,当执行指令“LOAD A 2000”时,操作数的实际地址是()。 A 1000 B 2000 C 3000 D 4000 15.虚拟内存的容量受到()的限制。

内存的存储管理--段式和页式管理的区别

存储管理的基本原理 内存管理方法 内存管理主要包括内存分配和回收、地址变换、内存扩充、内存共享和保护等功能。 下面主要介绍连续分配存储管理、覆盖与交换技术以及页式与段式存储管理等基本概念和原理。 1.连续分配存储管理方式 连续分配是指为一个用户程序分配连续的内存空间。连续分配有单一连续存储管理和分区式储管理两种方式。 (1)单一连续存储管理 在这种管理方式中,内存被分为两个区域:系统区和用户区。应用程序装入到用户区,可使用用户区全部空间。其特点是,最简单,适用于单用户、单任务的操作系统。CP/M和DOS 2.0以下就是采用此种方式。这种方式的最大优点就是易于管理。但也存在着一些问题和不足之处,例如对要求内存空间少的程序,造成内存浪费;程序全部装入,使得很少使用的程序部分也占用—定数量的内存。 (2)分区式存储管理 为了支持多道程序系统和分时系统,支持多个程序并发执行,引入了分区式存储管理。分区式存储管理是把内存分为一些大小相等或不等的分区,操作系统占用其中一个分区,其余的分区由应用程序使用,每个应用程序占用一个或几个分区。分区式存储管理虽然可以支持并发,但难以进行内存分区的共享。 分区式存储管理引人了两个新的问题:内碎片和外碎片。前者是占用分区内未被利用的空间,后者是占用分区之间难以利用的空闲分区(通常是小空闲分区)。为实现分区式存储管理,操作系统应维护的数据结构为分区表或分区链表。表中各表项一般包括每个分区的起始地址、大小及状态(是否已分配)。 分区式存储管理常采用的一项技术就是内存紧缩(compaction):将各个占用分区向内存一端移动,然后将各个空闲分区合并成为一个空闲分区。这种技术在提供了某种程度上的灵活性的同时,也存在着一些弊端,例如:对占用分区进行内存数据搬移占用CPU~t寸间;如果对占用分区中的程序进行“浮动”,则其重定位需要硬件支持。 1)固定分区(nxedpartitioning)。 固定式分区的特点是把内存划分为若干个固定大小的连续分区。分区大小可以相等:这种作法只适合于多个相同程序的并发执行(处理多个类型相同的对象)。分区大小也可以不等:有多个小分区、适量的中等分区以及少量的大分区。根据程序的大小,分配当前空闲的、适当大小的分区。这种技术的优点在于,易于实现,开销小。缺点主要有两个:内碎片造成浪费;分区总数固定,限制了并发执行的程序数目。 2)动态分区(dynamic partitioning)。 动态分区的特点是动态创建分区:在装入程序时按其初始要求分配,或在其执行过程中通过系统调用进行分配或改变分区大小。与固定分区相比较其优点是:没有内碎片。但它却引入了另一种碎片——外碎片。动态分区的分区分配就是寻找某个空闲分区,其大小需大于或等于程序

实验四可变分区存储管理方式的内存分配和回收

实验四 实验四可变分区存储管理方式的内存分配和回收 一.实验目的 通过编写和调试存储管理的模拟程序以加深对存储管理方案的理解,熟悉可变分区存储管理的内存分配和回收。 二.实验属性 设计 三.实验内容 1.确定内存空间分配表; 2.采用最优适应算法完成内存空间的分配和回收; 3.编写主函数对所做工作进行测试。 四.实验背景材料 实现可变分区的分配和回收,主要考虑的问题有三个:第一,设计记录内存使用情况的数据表格,用来记录空闲区和作业占用的区域;第二,在设计的数据表格基础上设计内存分配算法;第三,在设计的数据表格基础上设计内存回收算法。 首先,考虑第一个问题,设计记录内存使用情况的数据表格,用来记录空间区和作业占用的区域。 由于可变分区的大小是由作业需求量决定的,故分区的长度是预先不固定的,且分区的个数也随内存分配和回收变动。总之,所有分区情况随时可能发生变化,数据表格的设计必须和这个特点相适应。由于分区长度不同,因此设计的表格应该包括分区在内存中的起始地址和长度。由于分配时空闲区有时会变成两个分区:空闲区和已分分区,回收内存分区时,可能会合并空闲分区,这样如果整个内存采用一张表格记录己分分区和空闲区,就会使表格操作繁琐。分配内存时查找空闲区进行分配,然后填写己分配区表,主要操作在空闲区;某个作业执行完后,将该分区变成空闲区,并将其与相邻的空闲区合并,主要操作也在空闲区。由此可见,内存的分配和回收主要是对空闲区的操作。这样为了便于对内存空间的分配和回收,就建立两张分区表记录内存使用情况,一张表格记录作业占用分区的“己分分区表”;一张是记录空闲区的“空闲区表”。这两张表的实现方法一般有两种:一种是链表形式,一种是顺序表形式。在实验中,采用顺序表形式,用数组模拟。由于顺序表的长度必须提前固定,所以无论是“已分分区表”还是“空闲区表”都必须事先确定长度。它们的长度必须是系统可能的最大项数。 “已分分区表”的结构定义 #define n 10 //假定系统允许的最大作业数量为n struct { float address; //已分分区起始地址 float length; //已分分区长度、单位为字节 int flag; //已分分区表登记栏标志,“0”表示空栏目,实验中只支持一个字符的作业名 }used_table[n]; //已分分区表 “空闲区表”的结构定义

动态分区分配存储管理系统

动态分区分配存储管理系统 一、设计目的与内容 用高级语言编写和调试一个动态分区内存分配程序,演示实现下列两种动态分区分配算 法 1)首次适应算法 2)循环首次适应算法 1. 内存中有0-100M 的空间为用户程序空间,最开始用户空间是空闲的。 2. 作业数量、作业大小、进入内存时间、运行时间需要通过界面进行输入。 3. 可读取样例数据(要求存放在外部文件中)进行作业数量、作业大小、进入内存时间、 运行时间的初始化。 4. 根据作业进入内存的时间,采用简单的先进先出原则进行从外存到内存的调度,作业具 有等待(从外存进入内存执行)、装入(在内存可执行)、结束(运行结束,退出内存)三种状态。 5. 能够自动进行内存分配与回收,可根据需要自动进行紧凑与拼接操作。 二、算法的基本思想 1、定义基本结构: 1作业结构: typedef struct JOB { int num; //作业号 int size; //作业大小 int ctime; //作业进入时间 int rtime; //作业运行时间 int state; //作业状态 }Job ; 2)分区结构: typedef struct DuLNode { int ID; //分区号 int start; //开始地址 int size; //大小 int state; //0=尚未使用1=使用2=释放 struct DuLNode *prior;//前驱指针 struct DuLNode *next; //后即指针 }DuLNode, * DuLinkList;

2、基本操作: int Firstfit(int);//首次适应算法 int Next_fit(int); //循环首次适应算法 void showJob(int); //显示作业表 void showPartiton(DuLinkList);//显示分区表 DuLinkList InitpartitionList(DuLinkList &p);//初始化 void huishou(DuLinkList pl3,DuLinkList &pl);//回收函数 int Putin(int &n);//输入函数,输入作业相关信息 3、首次适应算法 空闲分区链以地址递增的次序链接,分配内存时,从链首开始顺序查找,直至找到一个大小能满足要求的空闲分区为止;然后再按照作业的大小,从该分区中划出一块内存空间分配给请求者,取消的空闲分区仍留在空闲链中。若从链首直至链尾都不能找到一个能满足要求的分区,则此次内存分配失败,返回。 4、循环首次适应算法 在为进程分配内存空间时,不再是每次都从链首开始查找,而是从上次找到的空闲分区的下一个空闲分区开始查找,直至找到一个能满足要求的空闲分区,从中划出一块与请求大小相等的内存空间分配给作业。

3.用C语言模拟实现可变式分区存储管理

3.用C语言模拟实现可变式 分区存储管理 -标准化文件发布号:(9556-EUATWK-MWUB-WUNN-INNUL-DDQTY-KII

试验三:用C语言模拟实现可变式分区存储管理 一、試驗目标: 1、通过编写可变式分区存储管理的C语言程序,使学生加强对可变式分区存储管理的认识。 2、掌握操作系统设计的基本原理、方法和一般步骤。 二、試驗内容:用C語言編寫一個实现可变式的分区管理的模擬程序。 *复习相关的知识: 1、分区管理的原理:将存储器划分成若干段大小固定的区域,一个区域里只能运行一个程序,程序只能在其自身所在的分区中活动。 2、固定式分区管理的原理:区域大小及起始地址是固定的。一个分区只能存放一个程序。需要设置一个分区说明表来标明内存的使用状态。根据分区说明表来给程序分配相应的区域。由于程序不可能刚刚占有一个分区的大小,这样就会在一个分区之中留下零头,造成了极大的浪费。 3、可变式分区管理的原理:区域的大小及起始地址是可变的,根据程序装入时的大小动态地分配一个区域。保证每个区域之中刚好放一个程序。这样可以充分地利用存储空间,提高内存的使用效率。如果一个程序运行完毕,就要释放出它所占有的分区,使之变成空闲区。这样就会出现空闲区与占用区相互交错的情况。这样就需要P表,F表来分别表示内存的占用区状态与空闲区的状态。 *确定该系统所使用的数据结构: 我们可以把内存表示为一个数组的形式。这个数组中的每一个单元都是一个无符号的字符型的数据类型。这样一个单元刚好占用一个字节的大小。这一个字节的地址可以用它在此数组中的下标来表示。如果一个程序占用了一定的区域,那么这个区域的大小就可以用它占有的字节数的个数来表示。用C语言可以表述如下: unsigned char memory[1024] 它就可以表示一个1K的内存空间。 为了实现可变式的分区管理,还需要设立两个表,一个是P表,一个是F表,它们分别表示内存的占用区状态。由于在该程序运行的过程之中需要不断地修改P表和F表,所以这两个表不适合于用数组的形式来表示;而应该使用单链表的形式。这样就要给单链表中的结点确立一个数据结构。很显然,P表中的每一个结点至少要包括以下的几项:占用的程序名、占用区的起始地址、占用区的大小、指向下一个结点的指针。F表中的结点可以不需要程序名这一项。但是为了统一起见,我们就统一地采用P表中的这种结点的结构。可以用C语言描述如下: struct node

相关文档
最新文档