磁盘存储空间的分配和回收
存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是计算机系统中的重要组成部分,它负责管理和分配计算机中的物理内存资源。
在计算机系统中,通过动态分区分配和回收算法来实现对这些资源的有效利用。
本文将介绍动态分区分配和回收算法的原理、主要算法以及优缺点。
动态分区分配是一种灵活、动态的内存分配方式,它根据进程的需求动态地分配内存空间。
动态分区分配算法有多种,其中最常用的有首次适应算法、最佳适应算法和最坏适应算法。
首次适应算法(First Fit)是最常用的分配算法之一、它从低地址开始寻找第一个满足要求的空闲分区来分配进程。
这种算法的优点是简单、高效,但是可能会产生大量的碎片空间,降低内存的利用率。
最佳适应算法(Best Fit)是在所有空闲分区中找到一个大小最适合进程的分区来分配。
它的主要思想是选择一个更接近进程大小的空闲分区,以减少碎片空间的产生。
然而,这种算法的缺点是需要遍历整个空闲分区链表,因此效率相对较低。
最坏适应算法(Worst Fit)与最佳适应算法相反,它选择一个大小最大的空闲分区来分配进程。
这种算法的好处是可以尽可能地保留大块的碎片空间,以便后续分配使用。
但是,它也会导致更多的碎片空间浪费。
动态分区的回收算法是用于回收被释放的内存空间并合并相邻的空闲分区,以尽量减少碎片空间的产生。
常见的回收算法有合并相邻空闲分区算法和快速回收算法。
合并相邻空闲分区算法会在每次有分区被回收时,检查是否有相邻的空闲分区可以合并。
如果有,就将它们合并为一个大的空闲分区。
这样可以最大程度地减少碎片空间,提高内存的利用效率。
快速回收算法是一种将被释放的分区插入到一个空闲分区链表的头部,而不是按照地址顺序进行插入的算法。
这样可以减少对整个空闲分区链表的遍历时间,提高回收的效率。
总结起来,动态分区分配和回收算法在存储管理中起着重要的作用。
首次适应算法、最佳适应算法和最坏适应算法是常用的动态分区分配算法,它们各自有着不同的优缺点。
磁盘存储空间的分配和回收1doc

磁盘存储空间的分配与回收一.实验内容:模拟实现磁盘空间的分配与回收.二.实验目的:磁盘格式化时,系统把磁盘存储空间分成许多磁道.每个磁道又分成若干个扇区(又叫做块).这些空间就是用来存放用户文件的.当用户的文件不再需要时,就应该删除.把一个文件存放到磁盘上时,可以组织成连续文件,链接文件,索引文件等.因此,磁盘空间的分配方法也有两种,一种是连续空间的分配;一种是不连续空间的分配(又叫动态分配).如何充分有效的利用磁盘空间,是操作系统应解决的重要课题之一.通过本实验,使学生对磁盘空间的分配与回收有一个较深入的理解.三.实验题目:1.用位示图管理磁盘空间,设计一个申请与申请与回收一个或几个磁盘块的分配与回收算法. 要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理过程.提示:(1)磁盘的位示图用若干个字节构成,每一位对应一个磁盘块.”1表示占用,”0”表示空闲.为了简单,假定现有一个磁盘组,共40个柱面.每个柱面四个磁道,每个磁道又划分成4个物理记录.假定字长为16位,其位示图如下图所示:(2)申请一个磁盘块时,由分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出它的柱面号,磁道号和扇区号).由位示图计算磁盘的相对块号的公式如下:相对块号=字号*16+位号之后再将相对块号转换成磁盘的物理地址:柱面号=相对块号/16的商,也即柱面号=字号磁道号=(相对块号/16的余数)/4的商,也即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,也即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置”0”.计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号*16+磁道号*4+物理块号再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号位号=磁道号*物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配.将分配相对块号返回用户,并将相对块号转换成磁盘绝对地址给以显示和系统各表和用户已分配的情况进行显示. (5)分配框图如图:(6)设计一个回收算法,将上述已分配的给用户的各盘块释放,并显示系统各表.收获与体会:通过进行操作系统的上机实验,我们从中可以更深刻的理解书本上的内容,以及操作系统中的一些最基本的原理.同时这也是对我们C语言的能力的一个锻炼和提高.在这几次上机实验中,我们还接触到了Linux系统,学会了该系统的最基本的使用方法,譬如挂载软盘,编译源程序等等,这也为我们以后更好的掌握该系统打下了很好的基础.但是从这次实践中,我们也感觉到自己在很多方面还存在不足,比如对某些函数的应用还不熟练,希望以后能多练习多实践,这样才能真正提高自己对课程的理解.附源程序:/*本程序顺序分配空间,所以运行后开始几个数字都是'1'*/#include<string.h>#include<stdio.h>#define ROW 12#define COLUMN 16#define AREA 192int a[ROW][COLUMN]={1,1,1,0,0,1,0,1,1,1,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,0,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,1,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0,1,1,1,1,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,1,1,0,1,0,1,1,0,};int b[ROW][COLUMN]={0};int c[AREA][3]={0};int static y;int input(int p);void distribute(int p);void callbackall(void);void callbackpointed(int n);main(){static int i,j,n,p;printf("**********************************");printf("********designed by weiwei********");printf("**********************************");printf("The distribution and callback of disk space.\n");printf("press any key to display the status of the disk.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}printf("Press any key to apply space from disk.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){if(a[i][j])continue;else{c[p][0]=p+1;c[p][1]=i*16+j;p++;}}}y=p;printf("There are %d blocks to use.",p);distribute(n);printf("\nThe next step is callbacking the space,press any key.\n");printf("You have these choices:\n");printf("1:\t Free all the disk blocks you apply just now\n");printf("2:\t Free a disk block that is destined \n");printf("3:\t Exit\n");i=input(3);while(i){switch(i){case 1:callbackall(n);break;case 2:callbackpointed(n);printf("\n\nYou stil have these choices:\n");printf("1:\t free all the disk blocks you apply just now\n");printf("2:\t free a pointed disk block\n");printf("3:\t esc\n");printf("Please make a choice:\n");i=input(3);break;case 3:exit(1);break;}}}int input(int p){static int k;scanf("%d",&k);if(k<=0||k>p){printf("Wrong input!!!!please enter a number that is greater than 0 and lessthan %d:\n",p);input(p);}return k;}void distribute(int x){static int i,j,k,p,m,n,q;printf("Please enter which disk block do you want to free from.\n");k=input(y);/*输入开始释放的量*/printf("Please enter how many disk blocks do you want to free.\n");printf("You must enssure the data is right\n");j=input(y);/*要释放多少个*/if(k+j>y){printf("Wrong input!!! The blocks you want to distribute is beyond the mark.\n ");printf("Please enter another legal number to be the first one and the amount:\n\n ");distribute(y);}else{for(i=k;i<k+j;i++){q=c[i-1][1];m=q/16;n=q%16;p=m*16+n;a[m][n]=1;b[m][n]=1;printf("%d:\t related block No. %d;cylinder No. %d;track No. %d;physic block No. %d\n",i,p,m,n/4,n%4);}printf("Press any key to compare this matrix to the last one\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}}void callbackall(int n){int i,j,m;for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){if(!b[i][j])continue;else{a[i][j]=0;}}}printf("press any key to compare this matrix to the first one.\n");getchar();printf("you can see it recruits:\n");for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}void callbackpointed(int n){static int i,k,q,m,j,p;printf("Please enter which disk block do you want to free from.\n");k=input(n);/*输入开始释放的量*/printf("Please enter how many disk blocks do you want to free.\n");printf("You must enssure the data is right\n");j=input(n);/*要释放多少个*/if(k+j>n+1){printf("Wrong input!!! The blocks you want to free is beyond the mark.\n ");printf("Please enter another legal number to be the first one and the amount:\n\n ");callbackpointed(n);}else{for(i=k;i<k+j;i++){q=c[i-1][1];m=q/16;p=q%16;a[m][p]=0;/*c[i-1][3]=1;c[k-1][3]=1表明已经被释放了*/}printf("The pointed disk block has been freeed,press any key to check the result.\n");getchar();for(i=0;i<ROW;i++){for(j=0;j<COLUMN;j++){printf("%d",a[i][j]);}printf("\n");}}}。
连续磁盘存储空间的分配和回收

/zhengjingwei1211@126/blog/static/61499280 20108217422645/磁盘存储空间的分配和回收(空闲表)#define N 5struct Empty // 空闲表结构体{int seq; //序号int start; //起始块号int count; //空闲块个数char state;//状态,F为未分配,E为空表目};struct Pan //磁盘结构体{int ZhuSeq; //柱面号int LapSeq; //磁道号int NoteSeq; //物理记录号int ZhuNum; //柱面个数int LapNum; //磁道个数int NoteNum; //物理记录个数};class CCiPan{public:Empty E[N]; //空闲表结构体数组Pan P; //磁盘public:void Display(Empty E[]); //显示空闲表void DeleteFile(Empty E[],Pan P); //删除文件,回收磁盘void CreateFile(Empty E[],Pan P); //创建文件,分配磁盘空间CCiPan();virtual ~CCiPan();};空闲表信息如下表:#include "stdafx.h"#include "CiPan.h"#include "stdio.h"#include "iostream.h"#define N 5///////////////////////////////////////////////////////////////////// /// Construction/Destruction///////////////////////////////////////////////////////////////////// /CCiPan::CCiPan(){//初始化空闲表E[0].seq=1;E[0].start=5;E[0].count=6;E[0].state='F';E[1].seq=2;E[1].start=14;E[1].count=3;E[1].state='F';E[2].seq=3;E[2].start=21;E[2].count=30;E[2].state='F';E[3].seq=4;E[3].state='E';E[4].seq=5;E[4].state='E';P.ZhuNum=200; //柱面数为200pNum=20; //磁道数为20P.NoteNum=6; //物理记录数为6}CCiPan::~CCiPan(){}void CCiPan::CreateFile(Empty E[],Pan P){int Block;Empty e;int i,j,M;cout<<"请输入所建立文件的记录块数:";cin>>Block;for(i=0;i<N;i++){if(i>=N-1 && E[i].count<Block){//当比较到最后一个未找到空闲块大小符合所要分配的文件大小时cout<<"磁盘空间不足!"<<endl;}if(E[i].count>Block){//当文件大小小于磁盘空闲块大小时,只改变空闲表中起始块号与空闲块个数M=E[i].start/P.NoteNum;P.ZhuSeq=M/P.ZhuNum; //计算柱面号pSeq=M%P.ZhuNum; //计算磁道号P.NoteSeq=E[i].start%P.NoteNum; //计算物理记录号E[i].start+=Block; //起始块号改变,增加量为文件大小E[i].count-=Block; //空闲块个数,减少量为文件大小cout<<endl;cout<<"成功为文件分配了磁盘空间!"<<endl;cout<<"为文件分配的物理地址为:"<<endl; //显示为文件分配的物理地址 cout<<"柱面号:"<<P.ZhuSeq<<endl;cout<<"磁道号:"<<pSeq<<endl;cout<<"物理记录号:"<<P.NoteSeq<<endl;break;}else{if(E[i].count==Block){ //文件大小与空闲块号个数刚好相等M=E[i].start/P.NoteNum;P.ZhuSeq=M/P.ZhuNum; //计算柱面号pSeq=M%P.ZhuNum; //计算磁道号P.NoteSeq=E[i].start%P.NoteNum; //计算物理记录号E[i].seq=N; //将刚分配出去的空间序号改为最后一项,等待将其插入到表末尾E[i].state='E'; //将状态改为“空表目”cout<<endl;cout<<"成功为文件分配了磁盘空间!"<<endl;cout<<"为文件分配的物理地址为:"<<endl;//显示为文件分配的物理地址 cout<<"柱面号:"<<P.ZhuSeq<<endl;cout<<"磁道号:"<<pSeq<<endl;cout<<"物理记录号:"<<P.NoteSeq<<endl;e=E[i]; //记录下刚分配出去的空闲块j=i;for(i=j;i<N;i++){//将状态为“空表目”的一项插入到表末尾E[i]=E[i+1];--E[i].seq; //向前移一项,序号减1E[N-1]=e;}break;}}}}void CCiPan::DeleteFile(Empty E[],Pan P){int i,j,m,k,n;Empty e,y;cout<<"请输入柱面号:";cin>>P.ZhuSeq;cout<<"请输入磁道号:";cin>>pSeq;cout<<"请输入物理记录号:";cin>>P.NoteSeq;cout<<"请输入块号:";cin>>m;for(i=0;i<N;i++){if(E[i].state=='E'){E[i].start=(P.ZhuSeq*pNum+pSeq)*P.NoteNum+P.NoteSeq; //计算起始块号E[i].count=m; //计算空闲块个数E[i].state='F';//回收后将状态改为“未分配”y=E[i];for(j=0;j<i;j++){if(E[j].start+E[j].count==E[i].start)//上临{if(E[i].start+E[i].count==E[j+1].start) //既上临又下临{E[j].count=E[i].count+E[j].count+E[j+1].count;E[j+1].count=' ';E[j+1].start=' ';E[j+1].state='E';E[j+1].seq=N;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"既上临又下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j].start<<"空闲块个数为:"<<E[j].count<<endl;e=E[j+1];k=j+1;for(n=k;n<N;n++){//将状态为“空表目”的一项插入到表末尾E[n]=E[n+1];--E[n].seq; //向前移一项,序号减1E[N-1]=e;}}else//只上临{E[j].count+=E[i].count;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"只上临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j].start<<"空闲块个数为:"<<E[j].count<<endl;}}else{if(E[i].start+E[i].count==E[j+1].start) //只下临{E[j+1].count+=E[i].count;E[j+1].start=E[i].start;E[i].start=' ';E[i].count=' ';E[i].state='E';cout<<"只下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[j+1].start<<"空闲块个数为:"<<E[j+1].count<<endl;}else//都不临{if(E[i].start>E[j].start && E[i].start<E[j+1].start){cout<<"既不上临又不下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[i].start<<"空闲块个数为:"<<E[i].count<<endl;for(int t=i;t>j+1;t--) //{E[t]=E[t-1];E[t].seq++;}E[j+1]=y;}else{if(E[i].start==E[j+1].start){E[j+1].start=E[i].start;E[j+1].count=E[i].count;E[j+1].state=E[i].state;cout<<"既不上临又不下临"<<endl;cout<<"回收文件后的起始块号为:"<<E[i].start<<"空闲块个数为:"<<E[i].count<<endl;}}}}}break;}}}void CCiPan::Display(Empty E[]){int i;cout<<"序号\t"<<"起始空闲块号\t"<<"空闲块个数\t"<<"状态"<<endl;for(i=0;i<N;i++){if(E[i].state=='F') //显示空闲表cout<<E[i].seq<<"\t"<<E[i].start<<"\t\t"<<E[i].count<<"\t\t"<<E[i] .state<<endl;elsecout<<E[i].seq<<"\t\t\t\t\t"<<E[i].state<<endl;}}/zx0071/blog/item/2490652da25cdeeb8a1399b4.html。
用位示图管理磁盘空间的分配与回收.doc

袇课程设计报告螈(2016--2017年度第二学期):操作系统实验薆课程名称:用位示图管理磁盘空间的分配与回收袃课设题目:控制与计算机工程学院羇院系:信安1401羅班级:黄竞昶羃姓名:贾静平薂指导教师:一周肇设计周数:莆成绩年 7月 9日螅2015莀一、需求分析蒁要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
螆( 1)假定现有一个磁盘组,共 40 个柱面。
每个柱面 4 个磁道,每个磁道又划分成 4 个物理记录。
磁盘的空间使用情况用位示图表示。
位示图用若干个字构成,每一位对应一个磁盘块。
1 表示占用, 0 表示空闲。
为了简单,假定字长为 16 位,其位示图如图 9— 1 所示。
系统设一个变量 S,记录磁盘的空闲块个数。
莃蒁 1 膇 2 袅 3 膂 4 薁 5 薈 6 莃 7 羁 8 蚀 9 蚅肅蚀螀肆薃膃位10 11 12 13 14 15袀螃字 0 蒇 1 芅 1 薂 1 羀 1 袈 1 蚂 0 芁 1 肀 0 羄 0 莄 1 聿 1 肀 1 莅 1 袂 1 肂 01膀 1袆 2....袁 39芀图 9—1 位示图( 2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0 的位,并计算磁盘的芇物理地址 ( 即求出柱面号、磁道号 ( 也即磁头号 ) 和扇区号 ) 。
肂由位示图计算磁盘的相对块号的公式如下:蚀相对块号一字号× 16+位号荿之后再将相对块号转换成磁盘的物理地址:蚈由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4× 4= 16,故柱面号=相对块号/ 16 的商,即柱面号=字号螄磁道号= ( 相对块号/ 16 的余数 ) /4 的商,即 ( 位号/ 4) 的商蚃物理块号= ( 相对块号/ 16 的余数 ) / 4 的余数,即 ( 位号/ 4) 的余数葿( 3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置 0。
磁盘存储空间的分配和回收

实习六磁盘存储空间得分配与回收一、实习内容模拟磁盘空闲空间得表示方法,以及模拟实现磁盘空间得分配与回收、二、实习目得磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。
用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上得文件删去,这就涉及到磁盘存储空间得分配与回收、一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、链接文件(串联文件)、索引文件等,因此,磁盘存储空间得分配有两种方式,一种就是分配连续得存储空间,另一种就是可以分配不连续得存储空间、怎样有效地管理磁盘存储空间就是操作系统应解决得一个重要问题,通过本实习使学生掌握磁盘存储空间得分配与回收算法。
三、实习题目本实习模拟三种磁盘存储空间得管理方法。
第一题:连续得磁盘存储空间得分配与回收。
[提示]:(1) 要在磁盘上建立顺序文件时,必须把按序排列得逻辑记录依次存放在磁盘得连续存储空间中。
可假定磁盘初始化时,已把磁盘存储空间划分成若干等长得块(扇区),按柱面号与盘面号得顺序给每一块确定一个编号、随着文件得建立、删除、磁盘存储空间被分成许多区(每一区包含若干块),有得区存放着文件,而有得区就是空闲得。
当要建立顺序文件时必须找到一个合适得空闲区来存放文件记录,当一个文件被删除时,则该文件占用得区应成为空闲区。
为此可用一张空闲区表来记录磁盘存储空间中尚未占用得部分,格式如下:(2)要建立文件时,先查找空闲区表,从状态为“未分配”得登记栏目中找出一个块数能满足要求得区,由起始空闲块号能依次推得可使用得其它块号、若不需要占用该区得所有块时,则剩余得块仍应为未分配得空闲块,这时要修改起始空闲块号与空闲块数、若占用了该区得所有块,则相应登记栏中得状态修改成“空表目”。
删除一个文件时,从空闲区表中找一个状态为“空表目”得登记栏目,把归还得起始块号与块数填入对应得位置。
磁盘存储空间得分配与回收算法类似于主存储器得可变分区方式得分配与回收。
存储管理动态分区分配及回收算法

存储管理动态分区分配及回收算法存储管理是操作系统中非常重要的一部分,它负责对计算机系统的内存进行有效的分配和回收。
动态分区分配及回收算法是其中的一种方法,本文将详细介绍该算法的原理和实现。
动态分区分配及回收算法是一种将内存空间划分为若干个动态分区的算法。
当新的作业请求空间时,系统会根据作业的大小来分配一个合适大小的分区,使得作业可以存储在其中。
当作业执行完毕后,该分区又可以被回收,用于存储新的作业。
动态分区分配及回收算法包括以下几个步骤:1.初始分配:当系统启动时,将整个内存空间划分为一个初始分区,该分区可以容纳整个作业。
这个分区是一个连续的内存块,其大小与初始内存大小相同。
2.漏洞表管理:系统会维护一个漏洞表,用于记录所有的可用分区的大小和位置。
当一个分区被占用时,会从漏洞表中删除该分区,并将剩余的空间标记为可用。
3.分区分配:当一个作业请求空间时,系统会根据作业的大小,在漏洞表中查找一个合适大小的分区。
通常有以下几种分配策略:- 首次适应(First Fit): 从漏洞表中找到第一个满足作业大小的分区。
这种策略简单快速,但可能会导致内存碎片的产生。
- 最佳适应(Best Fit): 从漏洞表中找到最小的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
- 最差适应(Worst Fit): 从漏洞表中找到最大的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
4.分区回收:当一个作业执行完毕后,系统会将该分区标记为可用,并更新漏洞表。
如果相邻的可用分区也是可合并的,系统会将它们合并成一个更大的分区。
总结来说,动态分区分配及回收算法是一种对计算机系统内存进行有效分配和回收的方法。
通过合理的分配策略和回收机制,可以充分利用内存资源,提高系统性能。
然而,如何处理内存碎片问题以及选择合适的分配策略是需要仔细考虑的问题。
存储器的分配与回收算法实现

存储器的分配与回收算法实现一、引言存储器的分配与回收算法是计算机操作系统中的重要内容之一。
它涉及到内存管理、进程管理等多个方面,对计算机系统的性能和稳定性都有着重要的影响。
本文将从存储器分配与回收算法的基本原理、常见算法及其实现方式等方面进行详细介绍。
二、存储器分配与回收算法基本原理1. 存储器分配在计算机系统中,进程需要使用一定数量的内存空间来运行。
因此,操作系统需要为每个进程分配一定数量的内存空间。
存储器分配就是指操作系统为进程分配内存空间的过程。
2. 存储器回收当一个进程不再需要使用某段内存空间时,操作系统需要将该段内存空间释放出来,以便其他进程使用。
这个过程称为存储器回收。
三、常见的存储器分配与回收算法1. 首次适应算法(First Fit)首次适应算法是最简单、最常用的一种内存分配方法。
该方法从低地址开始查找可用块,并选择第一个满足要求(大小大于或等于所需大小)的块进行分配。
优点:实现简单,效率高。
缺点:容易产生内存碎片,导致内存利用率低。
2. 最佳适应算法(Best Fit)最佳适应算法是一种比首次适应算法更为优化的算法。
该算法从所有可用块中选择最小的一个块进行分配。
优点:可以有效减少内存碎片,提高内存利用率。
缺点:实现复杂度高,效率较低。
3. 最差适应算法(Worst Fit)最差适应算法是一种与最佳适应算法相反的方法。
该方法选择可用块中最大的一个块进行分配。
优点:容易实现,效率较高。
缺点:会产生大量的内存碎片,降低了内存利用率。
4. 快速适应算法(Quick Fit)快速适应算法是一种基于链表结构的动态分配方法。
该方法将可用块按照大小分类,并将它们组织成多个链表。
当需要分配内存时,只需在对应大小的链表中查找可用块即可。
优点:能够快速地找到合适大小的空闲块,提高了效率和内存利用率。
缺点:实现复杂度较高,需要维护多个链表结构。
四、常见的存储器分配与回收算法实现方式1. 静态分配静态分配是指在程序运行之前就确定好内存的使用情况,将内存空间划分为不同的区域,并为每个区域分配固定大小的内存空间。
操作系统主存空间的分配与回收

操作系统主存空间的分配与回收操作系统是计算机系统中的核心软件,负责管理计算机硬件和软件资源,其中主存空间的分配和回收是操作系统的重要功能之一、本文将详细讨论主存空间的分配和回收的过程、策略,以及常见的分配和回收算法。
一、主存空间的分配主存空间的分配是指操作系统将主存划分为若干个固定或可变大小的分区,用于存储进程和数据。
主存空间的分配策略有静态分区分配和动态分区分配两种。
1.静态分区分配静态分区分配是在系统启动时将主存分为若干个固定大小的分区,每个分区都被预先分配给一些进程或作为系统保留区域。
由于分区是固定的,这种分配策略简单高效,但会造成主存空间的浪费。
常见的静态分区分配算法有等分算法和不等分算法。
-等分算法:将主存分为大小相等的分区,每个分区只能容纳一个进程。
对新进程的分配按顺序进行,如果一些分区已被占用,则无法分配。
这种算法简单,但会造成内存的浪费。
-不等分算法:将主存分为大小不同的分区,每个分区可以容纳一个或多个进程。
通过空闲分区列表来管理分区的分配和回收,按需分配满足进程大小的分区。
2.动态分区分配动态分区分配是根据进程的大小动态划分主存空间的分区,可以更充分地利用主存资源,避免内存的浪费。
常见的动态分区分配算法有首次适应算法、最佳适应算法和最坏适应算法等。
-首次适应算法:从主存的起始地址开始,找到第一个能满足进程大小的空闲分区进行分配。
该算法简单高效,但会产生很多内存碎片。
-最佳适应算法:从主存的空闲分区列表中选择能够满足进程大小并且具有最小空间的空闲分区进行分配。
该算法尽量避免内存碎片,但分配时间较长。
-最坏适应算法:从主存的空闲分区列表中选择能够满足进程大小并且具有最大空间的空闲分区进行分配。
该算法在提高系统效率的同时,可能会造成更多的内存碎片。
二、主存空间的回收主存空间的回收是指当一个进程终止或释放其已分配的主存时,将其占用的主存空间返还给操作系统的过程。
主存空间的回收可以通过重定位寄存器和内存管理单元(MMU)实现,具体过程如下:1.进程终止当一个进程终止时,操作系统会收回该进程占用的主存空间,并将其标记为空闲状态。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实习六磁盘存储空间的分配和回收一、实习容模拟磁盘空闲空间的表示方法,以及模拟实现磁盘空间的分配和回收。
二、实习目的磁盘初始化时把磁盘存储空间分成许多块(扇区),这些空间可以被多个用户共享。
用户作业在执行期间常常要在磁盘上建立文件或把已经建立在磁盘上的文件删去,这就涉及到磁盘存储空间的分配和回收。
一个文件存放到磁盘上,可以组织成顺序文件(连续文件)、文件(串联文件)、索引文件等,因此,磁盘存储空间的分配有两种方式,一种是分配连续的存储空间,另一种是可以分配不连续的存储空间。
怎样有效地管理磁盘存储空间是操作系统应解决的一个重要问题,通过本实习使学生掌握磁盘存储空间的分配和回收算法。
三、实习题目本实习模拟三种磁盘存储空间的管理方法。
第一题:连续的磁盘存储空间的分配和回收。
[提示]:(1) 要在磁盘上建立顺序文件时,必须把按序排列的逻辑记录依次存放在磁盘的连续存储空间中。
可假定磁盘初始化时,已把磁盘存储空间划分成若干等长的块(扇区),按柱面号和盘面号的顺序给每一块确定一个编号。
随着文件的建立、删除、磁盘存储空间被分成许多区(每一区包含若干块),有的区存放着文件,而有的区是空闲的。
当要建立顺序文件时必须找到一个合适的空闲区来存放文件记录,当一个文件被删除时,则该文件占用的区应成为空闲区。
为此可用一空闲区表来记录磁盘存储空间未占用的部分,格式如下:(2) 要建立文件时,先查找空闲区表,从状态为“未分配”的登记栏目中找出一个块数能满足要求的区,由起始空闲块号能依次推得可使用的其它块号。
若不需要占用该区的所有块时,则剩余的块仍应为未分配的空闲块,这时要修改起始空闲块号和空闲块数。
若占用了该区的所有块,则相应登记栏中的状态修改成“空表目”。
删除一个文件时,从空闲区表中找一个状态为“空表目”的登记栏目,把归还的起始块号和块数填入对应的位置。
磁盘存储空间的分配和回收算法类似于主存储器的可变分区方式的分配和回收。
同学们可参考实习四的第一题。
(3) 当找到空闲块后,必须启动磁盘把信息存放到指定的块中,启动磁盘必须给出由三个参数组成的物理地址:柱面号、磁道号和物理记录号。
故必须把找到的空闲块号换算成磁盘的物理地址。
为了减少移臂次数,磁盘上的信息按柱面上各磁道顺序存放。
现假定一个盘组共有200个柱面,(编号0-199)每个柱面有20个磁道(编号0-19,同一柱面上的各磁道分布在各盘面上,故磁道号即盘面号。
),每个磁道被分成等长的6个物理记录(编号0-5,每个盘面被分成若干个扇区,故每个磁道上的物理记录号即为对应的扇区号。
)。
那么,空闲块号与磁盘物理地址的对应关系如下:假设,则(4) 数,假定每个逻辑记录占磁盘上的一块,则可推算出归还后的起始空闲块号和块数,登记到空闲区表中。
换算关系如下:起始空闲块号=(柱面号´20+磁道号)´6+物理记录号 空闲块数=逻辑记录数(5) 请设计磁盘存储空间的分配和回收程序,要求把分配到的空闲块转换成磁盘物理地址,把归还的磁盘空间转换成空闲块号。
假定空闲区表的初值如提示(1)中指出,现有一文件要占用10块,运行你所设计的分配程序,显示或打印分配后的空闲区表以及分配到的磁盘空间的起始物理地址。
然后,有一文件被删除,它占用的磁盘空间为:1号柱面2号磁道,0号物理记录开始的4块,运行你所设计的回收程序,显示或打印回收后的空闲区表。
第二题:用位示图管理磁盘存储空间 [提示]:(1) 为了提高磁盘存储空间的利用率,可在磁盘上组织成文件、索引文件,这类文件可以把逻辑记录存放在不连续的存储空间。
为了表示哪些磁盘空间已被占用,哪些磁盘空间是空闲的,可用位示图来指出。
位示图由若干字节构成,每一位与磁盘上的一块对应,“1”状态表示相应块已占用,“0”状态表示该块为空闲。
位示图的形式与实习四中的位示图一样,但要注意,对于主存储空间和磁盘存储空间应该用不同的位示图来管理,绝不可混用。
(2) 申请一块磁盘空间时,由分配程序查位示图,找出一个为“0”的位,计算出这一位对应块的磁盘物理地址,且把该位置成占用状态“1”。
假设现在有一个盘组共80个柱面,每个柱面有两个磁道,每个磁道分成4个物理记录。
那么,当在位示图中找到某一字节的某一位为“0”时,这个空闲块对应的磁盘物理地址为:柱面号=字节号(3) 由回收程序根据归还的磁盘物理地址计算出归还块在位示图中的对应位,把该位置成“0”。
按照(2)中假设的盘组,归还块在位示图中的位置计算如下:字节号=柱面号位数=磁道号´4+物理记录号(4) 设计申请一块磁盘空间和归还一块磁盘空间的程序。
要求能显示或打印程序运行前和运行后的位示图;分配时把分配到的磁盘空间的物理地址显示或打印出来,归还时把归还块对应于位示图的字节号和位数显示或打印出来。
(5) 假定已有如表6-1的磁盘空间被占用了,现在要申请五块磁盘空间,运行分配程序,按(4)中要求显示或打印运行的结果。
然后再归还如表6-2的空间,运行回收程序,按(4)中的要求显示或打印运行结果。
表6-1表6-2第三题:模拟UNIX系统的空闲块成组法,实现磁盘存储空间的管理。
[提示]:(1) 假定磁盘存储空间已被划分成长度为n的等长块,共有M块可供使用。
UNIX系统中采用空闲块成组的方法来管理磁盘存储空间,将磁盘中的每N个空闲块(N<M)分成一组,最后一组可以不足N块,每组的第一块中登记了下一组空闲块的块数和块号,第一组的块数和块号登记在专用块中,登记的格式如下:当第一项容为“0”时,则第二项起指出的空闲块是最后一组。
(2) 现模拟UNIX系统的空闲块成组,假定共有8块可供使用,每3块为一组,则空闲块成组的初始状态为:开始时,空闲块号是顺序排列的,但经若干次的分配和归还操作后,空闲块的就未必按序排列了。
用二维数组A:array [0…M-1] of array [0…n-1]来模拟管理磁盘空间,用A[i]表示第I块,第0块A[0]作为专用块。
(3) 成组的分组情况记录在磁盘物理块中,为了查找情况,必须把它们读入主存,故当磁盘初始化后,系统先将专用块容复制到主存中。
定义一个数组MA存放专用块容,即MA: =A[0]。
申请一块磁盘空间时,查MA,从中找出空闲块号,当一组的空闲块只剩第一块时,则应把该块中指出的下一组的空闲块数和块号复制到专用块中,然后把该块分配给申请者。
当一组的空闲块分配完后则把专用块容(下一组情况)复制到主存,再为申请者分配。
分配算法如图6-1。
图6-1 采用成组的分配算法(4) 归还一块时给出归还的块号,叵当前组不满规定块数时,将归还块登记入该组;若当前组已满,则另建一新组,这时归还块作为新一组的第一块,应把主存中登记的一组情况MA复制到归还块中,然后在MA重新登记一个新组。
归还一块的算法如图6-2。
图6-2 采用成组的回收算法(5) 设计分配和归还磁盘空间的程序,能显示或打印分配的磁盘空间的块号,在完成一次分配或归还后能显示或打印各空闲块组的情况(各组的空闲块数和块号)。
本实习省去了块号与物理地址之间的转换工作,而在实际的系统中必须进行块号与物理地址的转换工作。
(6) 运行你所设计的程序,假定空闲块的初始状态如提示(2),现先分配4块,再依次归还第2块和第6块。
把执行后分配到的块号依次显示或打印出来,且显示或打印空闲块组的情况。
在上次执行的基础上继续分配3块,然后归还第1块,再申请5块,显示或打印依次分配到的块号及空闲块组情况。
四、相关数据结构及说明struct freeblock {int FBbegin;//起始空闲块号int num;//空闲块数char state;//状态struct freeblock *next; }struct filetowrite {char name[10];//文件名int size;//文件大小int addr_cylinder;//装入磁盘的首地址_柱面号int addr_track;//装入磁盘的首地址_磁道号int addr_note;//装入磁盘的首地址_物理记录号struct filetowrite *next; }六、源代码及注释1、题一源代码:#include<stdlib.h>#include<stdio.h>int getmalloc()//分配磁盘空间{int flag=0;struct freeblock *p=FBhead;struct filetowrite *File;File=(struct filetowrite *)malloc(sizeof(struct filetowrite));printf("输入要装入的文件名:");scanf("%s",File->name);printf("输入所需的磁盘空间大小:");scanf("%d",&File->size);for(p=FBhead->next;p!=NULL;p=p->next)if((File->size)<=(p->num))//分配空间{flag=1;File->addr_cylinder=((p->FBbegin)/6)/20;File->addr_track=((p->FBbegin)/6)%20;File->addr_note=(p->FBbegin)%6;File->next=Filehead->next;//加入文件链表Filehead->next=File;if((File->size)<(p->num))//修改该快的起始地址和块数{p->FBbegin=p->FBbegin+File->size;p->num=p->num-File->size; }else p->state='U';break; }if(flag==0)printf("抱歉!目前没有足够的磁盘空间分配给该文件.\n");else {printf("分配磁盘成功!\n该文件的物理地址:\n柱面号\t磁道号\t物理块号\n ");printf(" %d\t %d\t %d\n",File->addr_cylinder,File->addr_track,File ->addr_note); } }int deletelfree()//回收磁盘空间{char name[10]; int flag=0;struct filetowrite *p;printf("输入要删除的文件名:");scanf("%s",&name);for(p=Filehead;p->next!=NULL;p=p->next){if(strcmp(p->next->name,name)==0)//找到该文件{flag=1;int funion=0,nunion=0;int m=p->next->addr_cylinder;int n=p->next->addr_track;int k=p->next->addr_note;int addr=(m*20+n)*6+k;//起始空闲块号int tail=p->next->size+addr;struct freeblock *pnode,*qnode,*tnode,*snode;pnode=FBhead->next;while(pnode!=NULL)//先考虑和后面的部分或许有合并的情况{if((pnode->FBbegin)==tail){pnode->FBbegin=addr;pnode->num=pnode->num+p->next->size;nunion=1;break; }pnode=pnode->next; }qnode=FBhead->next;while(qnode!=NULL)//再考虑是否和前面的可以合并{if((qnode->FBbegin+qnode->num)==addr){if(nunion==0){qnode->num=qnode->num+p->next->size;funion=1;break; }else{qnode->num=qnode->num+pnode->num;tnode=FBhead;while(tnode->next!=pnode)tnode=tnode->next;tnode->next=pnode->next;free(pnode);funion=1;break;}}qnode=qnode->next; }if(funion==0&&nunion==0)//若没有和前面的或后面的进行合并,则新建一个表目{snode=(struct freeblock *)malloc(sizeof(struct freeblock));snode->FBbegin=addr;snode->num=p->next->size;snode->state='F';if(FBhead->next==NULL){FBhead->next=snode;snode->next=NULL;}else{snode->next=FBhead->next;FBhead->next=snode; }}struct filetowrite *q;q=p->next;//除该文件p->next=p->next->next;free(q); break; } }if(flag==0)printf("没有该文件!\n");else {printf("文件删除成功!\n"); }int dispfree()//显示磁盘空闲区表{int i=1;struct freeblock *p=FBhead;printf("\n磁盘空闲区表\n");printf("序号\t起始空闲块号\t空闲块个数\t 状态\n");for(p=FBhead->next;p!=NULL;p=p->next){if((p->state)=='F')printf(" %d\t %d\t\t %d\t\t未分配\n",i++,p->FBbegin,p->num);elseprintf(" %d\t\t\t\t\t空表目\n",i++); } }int dispfile(){char name[10];struct filetowrite *p=Filehead; printf("输入要查看的文件名:");scanf("%s",&name);for(p=Filehead->next;p!=NULL;p=p->next){if(strcmp(p->name,name)==0) {printf("该文件的物理地址:\n柱面号\t磁道号\t物理块号\n ");printf(" %d\t %d\t %d\n",p->addr_cylinder,p->addr_track,p->add r_note); break; } }if(p==NULL)printf("没有该文件!\n"); }int main() {int n,i,A[MAX],B[MAX];//A[MAX]表示起始空闲块号,B[MAX]表示空闲块个数char ch;struct freeblock *pnew;FBhead=(struct freeblock *)malloc(sizeof(struct freeblock));FBhead->next=NULL;printf("输入磁盘空闲区个数:");scanf("%d",&n);for(i=1;i<=n;i++) {pnew=(struct freeblock *)malloc(sizeof(struct freeblock) );pnew->next=NULL;pnew->next=FBhead->next;FBhead->next=pnew;printf("起始空闲块号:");scanf("%d",&pnew->FBbegin);printf("空闲块个数:");scanf("%d",&pnew->num); pnew->state='F';pnew=pnew->next; }Filehead=(struct filetowrite *)malloc(sizeof(struct filetowrite));Filehead->next=NULL;do {system("cls");printf("\n\t\t ********** 主菜单**********\n\n");printf("\t\t\t1.新建文件\n");printf("\t\t\t2.删除文件\n");printf("\t\t\t3.查看磁盘\n");printf("\t\t\t4.查看文件\n");printf("\t\t\t5.退出\n"); printf("请选择:");scanf("%c",&ch);switch(ch) {case '1':getmalloc();system("pause");break;case '2':deletelfree();system("pause");break;case '3':dispfree();system("pause");break;case '4':dispfile();system("pause");break;case '5':exit(1);break;default:printf("输入错误!请重新输入.\n");}printf("\n");getchar(); }while(ch!=4);return 0;2、题二源代码:#include <stdio.h>#include <process.h>void Initbitmap(int map[8][8]) {int cylinder,track,sector;char choice='Y';printf("初始化位视图...\n");while(choice=='y'||choice=='Y') {printf("柱面号:");scanf("%d",&cylinder);printf("磁道号:");scanf("%d",&track);printf("物理记录号:");scanf("%d",§or);map[cylinder][4*track+sector]=1;printf("contiune?");getchar();scanf("%c",&choice); } }void allocate(int map[8][8]) {int i,j;int flag=0;int cylinder,track,sector;for(i=0;i<8;i++){ for(j=0;j<8;j++)if(map[i][j]==0){map[i][j]=1;flag=1;break;}if(flag==1) break;}if(flag==1){cylinder=i; track=j/4; sector=j%4; printf("分配到的柱面号、磁道号、物理记录数");printf("%d\t%d\t%d",cylinder,track,sector);printf("\n"); }else printf("空间不足,分配失败!"); }void reclaim(int map[8][8]){ int cylinder,track,sector;printf("柱面号:");scanf("%d",&cylinder);printf("磁道号:");scanf("%d",&track);printf("物理记录号:");scanf("%d",§or);if(map[cylinder][4*track+sector]==0) {printf("此块为未分配块!回收出错!");getchar(); }else {map[cylinder][4*track+sector]=0;printf("回收块对应的字节号:%4d\t位数:%4d\n",cylinder,4*track+sector); } }void main() {int bitmap[8][8]; int i,j; int choice;or(i=0;i<8;i++) for(j=0;j<8;j++)bitmap[i][j]=0; Initbitmap(bitmap);while(1) {printf("\n请输入选择:");printf("1--分配,2---回收,3--显示位示图,0--退出\n");scanf("%d",&choice); switch(choice) {case 1:allocate(bitmap);break;case 2:reclaim(bitmap);break;case 3:for(i=0;i<8;i++){for(j=0;j<8;j++)printf("%8d",bitmap[i][j]);printf("\n"); }break;case 0:exit(0);default:printf("错误选择!");break; } } }3、第三题源程序:#include<stdio.h>int MA[4]; /*空闲块数组*/int A[9][4]={{3,1,2,3},{3,4,5,6},{0,0,0,0},{0,0,0,0},{3,0,7,8}, {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}; /*磁盘空间*/int mark[9]; /*存放已分配的块*/int No=0; /*已分配的块数*/void display1(){ int i,j,temp,count, No=0;if(MA[1]!=0){ i=MA[0];printf("\ngroup1:");for(j=1;j<=i;j++){ printf("%d ",MA[j]);mark[++No]=MA[j]; }temp=MA[1];count=2;while(A[temp][1]!=0){ printf("\ngroup%d:",count);i=A[temp][0];for(j=1;j<=i;j++){ printf("%d ",A[temp][j]);mark[++No]=A[temp][j]; }count++;temp=A[temp][1]; }printf("\ngroup%d:",count);i=A[temp][0];for(j=2;j<=i+1;j++)if(A[temp][j]>0){ printf("%d ",A[temp][j]);mark[++No]=A[temp][j]; } }else{ i=MA[0];if(i==1)printf("\nThe blocks are all assigned");else{ printf("\ngroup1:");for(j=2;j<=i;j++){ printf("%d ",MA[j]);mark[++No]=MA[j];} } } }void display() /*显示分组情况*/{ int i,j;if(MA[0]!=0)display1();else{ i=MA[1];for(j=0;j<=3;j++)MA[j]=A[i][j];display1(); } }void assign() /*分配空闲块*/{ int s,i;if(MA[0]>1) /*若该组不止一个空闲块*/{ i=MA[0];s=MA[i];MA[0]--;printf("\nnumber of the block:%d",s); }else if(MA[0]==1) /*只剩一个空闲块*/{ if(MA[1]!=0) /*还有其它空闲块组*/{ s=MA[1];for(i=0;i<=3;i++)A[0][i]=A[s][i];MA[0]--;printf("\nnumber of the block:%d",s); }else /*没有其它空闲块组*/{ printf("\nThere isn't any space");return; } }else /*当前组已分配完*/{ for(i=0;i<=3;i++)MA[i]=A[0][i];assign(); }display(); /*显示分组情况*/}void callback() /*回收空闲块*/{ int i,j,temp;printf("\ninput the No. of the block you want to callback:");scanf("%d",&j);getchar(); /*得到待回收的空闲块号*/for(temp=1;temp<=No;temp++) { if(mark[temp]==j) break; }if(temp<No+1) /*若该空闲块已在,退出*/{ printf("\nThe block is in the disk"); return; }if(MA[0]<3) /*当前组不满3块*/{ i=MA[0]; MA[i+1]=j; MA[0]++; }else /*已有3块*/{ for(i=0;i<=3;i++) A[j][i]=MA[i]; MA[0]=1; MA[1]=j; }display(); /*显示*/}void menu() /*功能选择函数*/{ int choice; char judge;printf("\ninput your choice:(1--assign,2--callback):");scanf("%d",&choice);getchar();if(choice==1)assign();else if(choice==2)callback();elseprintf("\ninvalid command!");printf("\ncontinue or not (y--Yes,n--Not):");scanf("%c",&judge);getchar();if(judge=='y')menu();else{ printf("\nNow the graph is:"); display();printf("\npress any key to quit"); getchar(); } }int main() { int i;for(i=0;i<=3;i++)MA[i]=A[0][i]; display(); menu(); }七、运行结果1、题一运行结果:2、题二运行结果:3、题三运行结果:。