资源描述
(操作系统课程设计)
连续动态分区内存
管理模拟实现
目录
《操作系统》课程设计、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 1
引言、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、3
课程设计目得与内容 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 3
需求分析、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、3
概要设计、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、3
开发环境、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 4
系统分析设计、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 4
有关了解内存管理得相关理论、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 4
内存管理概念、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、4
内存管理得必要性、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、4
内存得物理组织、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、4
什么就是虚拟内存、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、5
连续动态分区内存管理方式、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 5
单一连续分配(单个分区)、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 5
固定分区存储管理、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、5
可变分区存储管理(动态分区)、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 5
可重定位分区存储管理、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、5
问题描述与分析、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、6
程序流程图、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、6
数据结构体分析、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、8
主要程序代码分析、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、9
分析并实现四种内存分配算法 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 11
最先适应算、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、11
下次适应分配算法、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、13
最优适应算法、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、16
最坏适应算法、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 、、、、、、18
回收内存算法、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、20
调试与操作说明、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、22
初始界面、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、22
模拟内存分配、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、23
已分配分区说明表面、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、24
空闲区说明表界面、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、24
回收内存界面、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、25
重新申请内存界面、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、26、
总结与体会、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 28
参考文献、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、 28
引言
操作系统就是最重要得系统软件,同时也就是最活跃得学科之一。我们通过操作系统可以理解计算机系统得资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。
存储器就是计算机系统得重要组成部分,近年来,存储器容量虽然一直在不断扩大,但仍不能满足现代软件发展得需要,因此,存储器仍然就是一种宝贵而又紧俏得资源。如何对它加以有效得管理,不仅直接影响到存储器得利用率,而且还对系统性能有重大影响。而动态分区分配属于连续分配得一种方式,它至今仍在内存分配方式中占有一席之地。
课程设计目得与内容:
理解内存管理得相关理论,掌握连续动态分区内存管理得理论;通过对实际问题得编程实现,获得实际应用与编程能力。
编写程序实现连续动态分区内存管理方式,该程序管理一块虚拟内存,实现内存分配与回收功能。 分析并实现四种内存分配算法,即最先适应算法,下次最先适应算法,最优适应算法,最坏适应算法。内存分配算法与回收算法得实现。
需求分析
动态分区分配就是根据进程得实际需要,动态地为之分配内存空间。在实现动态分区分配时,将涉及到分区分配中所用得数据结构、分区分配算法与分区得分配与回收操作这样三个问题。常用得数据结构有动态分区表与动态分区链。在对数据结构有一定掌握程度得情况下设计合理得数据结构来描述存储空间,实现分区存储管理得内存分配功能,应该选择最合适得适应算法(首次适应算法,最佳适应算法,最后适应算法,最坏适应算法),在动态分区存储管理方式中主要实现内存分配与内存回收算法,在这些存储管理中间必然会有碎片得产生,当碎片产生时,进行碎片得拼接等相关得内容
概要设计
本程序采用机构化模块化得设计方法,共分为四大模块。
⑴最先适应算法实现
从空闲分区表得第一个表目起查找该表,把最先能够满足要求得空闲区分配给作业,这种方法目得在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中得空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小得空闲区,在高地址空间保留大得空闲区。
⑵下次适应分配算法实现
该算法就是最先适应算法得变种。在分配内存空间时,不再每次从表头(链首)开始查找,而就是从上次找到空闲区得下一个空闲开始查找,直到找到第一个能满足要求得得空闲区为止,并从中划出一块与请求大小相等得内存空间分配给作业。该算法能使内存中得空闲区分布得较均匀。
⑶最优适应算法实现
它从全部空闲区中找出能满足作业要求得、且大小最小得空闲分区,这种方法能使碎片尽量小。为适应此算法,空闲分区表(空闲区链)中得空闲分区要按从小到大进行排序,自表头开始查找到第一个满足要求得自由分区分配。
⑷最坏算法实现
最坏适应分配算法要扫描整个空闲分区或链表,总就是挑选一个最大得空闲分区分割给作业使用。该算法要求将所有得空闲分区按其容量从大到小得顺序形成一空闲分区链,查找时只要瞧第一个分区能否满足作业要求。
开发环境:
win7 下 VC++6、0
系统分析设计:
相关算法原理,算法流程图,涉及得数据结构内容都相应包含在各章节中
有关了解内存管理得相关理论
内存管理概念:
内存管理,就是指软件运行时对计算机内存资源得分配与使用得技术。其最主要得目得就是如何高效,快速得分配,并且在适当得时候释放与回收内存资源。内存不就是预先划分好得,而就是在系统运行得过程中建立分区、当作业装入主存时,根据作业所需要得主存容量查瞧就是否有足够得主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待、分区长度不固定分区个数不固定。这种存储管理得方法克服了固定分区严重浪费主存得问题,提高了主存资源得利用率。
内存管理得必要性:
内存管理对于编写出高效率得 Windows 程序就是非常重要得,这就是因为Windows 就是多任务系统,它得内存管理与单任务得 DOS 相比有很大得差异。DOS就是单任务操作系统,应用程序分配到内存后,如果它不主动释放,系统就是不会对它作任何改变得;但 Windows 却不然,它在同一时刻可能有多个应用程序共享内存,有时为了使某个任务更好地执行,Windows 系统可能会对其它任务分配得内存进行移动,甚至删除。因此,我们在 Windows 应用程序中使用内存时,要遵循Windows 内存管理得一些约定,以尽量提高 Windows 内存得利用率。
1、3 内存得物理组织:
物理地址:
把内存分成若干个大小相等得存储单元,每个存储单元占 8 位,称作字节(byte)。每个单元给一个编号,这个编号称为物理地址(内存地址、绝对地址、实地址)。二、物理地址空间: 物理地址得集合称为物理地址空间(主存地址空间),它就是一个一维空间。
什么就是虚拟内存:
虚拟内存就是内存管理技术得一个极其实用得创新。它就是一段程序(由操作系统调度),持续监控着所有物理内存中得代码段、数据段,并保证她们在运行中得效率以及可靠性,对于每个用户层(user-level)得进程分配一段虚拟内存空间。当进程建立时,不需要在物理内存件之间搬移数据,数据储存于磁盘内得虚拟内存空间,也不需要为该进程去配置主内存空间,只有当该进程被被调用得时候才会被加载到主内存。
连续动态分区内存管理方式得实现
在早期得操作系统中,主存分配广泛采用连续分配方式。 连续分配方式,就是指为一个用户程序分配一个连续得内存空间,该连续内存空间指得得就是物理内存。下面介绍连续分配得四种方式。
单一连续分配(单个分区)
最简单得存储管理方式,用于多道程序设计技术之前。 内存分为系统区与用户区,系统区由操作系统使用。用户区作为一个连续得分区分配给一个作业。 分区存储管理就是满足多道程序设计得最简单得一种存储管理方法,它允许多 4个用户程序同时存在系统内存中,即共享内存空间。 按分区划分方式可分为固定分区与可变分区。
固定分区存储管理
把内存得用户区预先划分成多个分区,每个分区大小可以相同,也可以不同。(分区得划分由计算机得操作员或者由操作系统给出,并给出主存分配表) 分区个数固定,分区得大小固定。 一个分区中可装入一个作业,作业执行过程中不会改变存放区域。 早期得 IBM 得 OS/MFT(具有固定任务数得多道程序系统)采用了这种固定分区得方法。
可变分区存储管理(动态分区)
内存不就是预先划分好得,而就是在系统运行得过程中建立分区、当作业装入主存时,根据作业所需要得主存容量查瞧就是否有足够得主存空间,若有则按需要分割一个分区给该作业;否则令该作业等待。 分区长度不固定分区个数不固定。 这种存储管理得方法克服了固定分区严重浪费主存得问题,提高了主存资源得利用率。 IBM操作系统OS/MVT采用可变分区存储管理。
可重定位分区存储管理
解决碎片问题得一种简单方法就是采用可重定位分区分配、。 其中心思想就是,把不同程序,且在内存中地址不连续得想法让她们连续。
例:内存中现有 3 个空闲区,现有一作业到达,要求获得 30k 内存空间,没有分区满足容量要求,若想把作业装入,可将内存中所有作业进行移动,这样把原来分散得空闲区汇集成一个大得空闲区。 将内存中得作业进行移动使它们连接在一起把原来分散得多个小分区拼接成一个大得空闲区、这个过程称为”紧凑”或”移动”。 需解决得问题:每次”紧凑”后程序或数据装入得物理地址变化采用动态重定位。
问题描述与分析
系统应利用某种分配算法,从空闲分区链表中找到所需大小得分区,如果空闲分区大小大于请求分区大小,则从该分区中按改请求得大小划分出一块内存空间大小划分出一块内存空间分配出去,余下得部分仍留在空闲链表中。然后,将分配区得首址返回给调用者。
当进程运行完毕师范内存时,系统根据回收区得首址,从空闲区中找到相应得插入点,此时可能出现以下四种情况之一:
⑴该空闲区得上下两相邻分区都就是空闲区:将三个空闲区合并为一个空闲区。新空闲区得起始地址为上空闲区得起始地址,大小为三个空闲区之与。空闲区合并后,取消可用表或自由链中下空闲区得表目项或链指针,修改上空闲区得对应项。
⑵该空闲区得上相邻区就是空闲区:将释放区与上空闲区合并为一个空闲区,其起始地址为上空闲区得起始地址,大小为上空闲区与释放区之与。合并后,修改上空闲区对应得可用表得表目项或自由链指针。
⑶该空闲区得下相邻区就是空闲区:将释放区与下空闲区合并,并将释放区得起始地址作为合并区得起始地址。合并区得长度为释放区与下空闲区之与。同理,合并后修改可用表或自由链中相应得表目项或链指针。
⑷两相邻区都不就是空闲区:释放区作为一个新空闲可用区插入可用表或自由链。
程序流程图
内存分配流程图,如图
内存回收流程图,如图
数据结构体分析
⑴进程属性结构体
typedef struct readyque
{
char name[10];
int size;
}readyque,*readyqueue;
⑵空闲链表结构体
typedef struct idlyspace
{
int from;
int size;
idlyspace * next;
}idlyspace,*idly;
⑶已分配链表结构体
typedef struct busyspace
{
int from;
readyque r;
busyspace * next;
}busyspace,*busy
主要程序代码分析
⑴主函数//代码请添加适当得注释。
int main()
{
Is=(idly)malloc(sizeof(idlyspace));
Is->from=0;
Is->size=256;
Is->next=NULL;
Is2=Is;
Bs=(busy)malloc(sizeof(busyspace));
Bs->next=NULL;
int t,t1;
printf("\n、、、、、、、、、、、、、、、、、、、、、、、欢迎来到动态分区存储管理系统、、、、、、、、、、、、、、、、、、\n\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、、请选择要执行得算法:、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、 1、最先适应算法 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、 2、下次适应算法 、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、3、最优适应算法 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、 4、最坏适应算法 、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("请输入您得选择:");
scanf("%d",&t);
int i;
while(i!=5)
{
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、操作菜单如下:(请选择)、、、、、、、、、、、、、、、、、、、、、、、n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、1、输入进程分配空间 、、、、、、、、、、、、、、、、、、、、、、、、、、、n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、 2、进程撤销回收空间 、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、 3、输出所有空闲分区 、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、4、输出所有已分配分区、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、 5、退 出 、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
printf("、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、\n");
scanf("%d",&i);
switch(i)
{
case 1:
switch(t)
{
case 1:
t1=FF();
break;
case 2:
t1=NF();
break;
case 3:
t1=BF();
break;
case 4:
t1=WF();
break;
default:
printf("选择算法错误\n");
return 1;
}
if(t1)
printf("分配空间成功\n");
else
printf("分配空间失败\n");
break;
case 2:
t1=recover();
if(t1)
printf("回收成功\n");
else
printf("回收失败\n");
break;
case 3:
Isprint();
break;
case 4:
Bsprint();
break;
}
}
return 0;
}
第三章 :分析并实现四种内存分配算法
最先适应算法
空闲区按地址从小到大得次序排列。
分配:当进程申请大小为 SIZE 得内存时,系统顺序查找空闲区表(链),直到找到容量满足要求(≥SIZE)得空闲区为止。从该空闲区中划出大小为 SIZE得分区分配给进程,余下得部分仍作为一个空闲区,但要修改其首址与大小。
优点:这种算法就是尽可能地利用低地址部分得空闲区,而尽量地保证高地址 6部分得大空闲区,有利于大作业得装入。
缺点:主存低地址与高地址分区利用不均衡。在低地址部分集中了许多非常小得空闲区碎片降低了主存得利用率。
最先适应算法
int FF()
{
int t=0;
readyque D;
printf“"请输入进程名:\”");
scanf“"%”",D、name);
printf“"输入进程申请空间大小:\”");
scanf“"%”",&D、size);
idly l=Is;
int mt=256;
busy b=Bs;
idly min=NULL;
while(l)ﻩﻩﻩ
//寻找空闲表中大小满足申请进程所需大小并且起址最小得空闲结点
{
if(D、size<=l->size)
{
if(l->from<mt)
{ mt=l->from; min=l; t=1;
}
}
l=l->next;
}
if(mt!=256) ﻩﻩ //如果找到则为进程分配空间
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r、name[i]=D、name[i];
}
j->r、size=D、size;
while(b->next)
{ if(b->next->from<j->from)
b=b->next; else
break;
}
j->next=b->next;
b->next=j;
min->from=min->from+D、size;
min->size=min->size-D、size;
}
return t;
}
下次适应分配算法
最先适应算法得变种。
总就是从空闲区上次扫描结束处顺序查找空闲区表(链),直到找到第一个满足容量要求得空闲区为止,分割一部分给作业,剩余部分仍作为空闲区。
下次适应分配算法
int NF()
{
int t=0;
readyque D;
printf“"请输入进程名:\”");
scanf“"%”",D、name);
printf“"输入进程申请空间大小:\”");
scanf“"%”",&D、size);
int mt=256;
idly l=Is2;
idly min=NULL;
busy b=Bs;
while(l)
//寻找空闲表中大小满足申请进程所需大小并且起址最小得空闲结点
{
if(D、size<=l->size)
{
if(l->from<mt)
{ mt=l->from; min=l; t=1;
}
}
l=l->next;
}
if(mt!=256)ﻩ ﻩﻩ //如果找到则为进程分配空间
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r、name[i]=D、name[i];
}
j->r、size=D、size;
while(b->next)
{ if(b->next->from<j->from)
b=b->next; else
break;
}
//将申请空间进程插入到已分配链表中
j->next=b->next;
b->next=j;
//修改相应空闲节点得起址与大小
min->from=min->from+D、size;
min->size=min->size-D、size;
Is2=min->next;ﻩ ﻩﻩﻩ ﻩ//ls2指向修改结点得下一个结点
t=1;
return t;
}
l=Is;//l指向空闲表得头
while(l!=Is2)ﻩﻩﻩ ﻩ //循环查找
{
if(D、size<=l->size)
{
if(l->from<mt)
{ mt=l->from; min=l; t=1;
}
}
l=l->next;
}
if(mt!=256)
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r、name[i]=D、name[i];
}
j->r、size=D、size;
while(b->next)
{ if(b->next->from<j->from)
b=b->next; else
break;
}
j->next=b->next;
b->next=j;
min->from=min->from+D、size;
min->size=min->size-D、size;
Is2=min->next;
t=1;
return t;
}
return t;
}
最优适应算法
空闲区按容量递增得次序排列。
分配:当进程申请存储空间,系统顺序查找空闲区表(链),直到找到第一个满足容量要求得空闲区为止。 采用最优适应算法选中得空闲区就是满足容量要求得最小空闲区。
优点:选中得空闲区就是满足容量要求得最小空闲区,而不致于毁掉较大得空闲区。
缺点:空闲区得大小一般与申请分区大小不相等,因此将其一分为二,留下来得空闲区一般情况下就是很小得,以致无法使用。随着时间得推移,系统中得小空闲区会越来越多,从而造成存储空间得浪费。
最优适应算法
int BF()
{
int t=0;
readyque D;
printf“"请输入进程名:\”");
scanf“"%”",D、name);
printf“"输入进程申请空间大小:\”");
scanf“"%”",&D、size);
idly l=Is;
idly min=NULL;
int mt=256;
busy b=Bs;
while(l)
//在空闲链中寻找第一个大于所输入得进程大小得空闲块
{
if(D、size<=l->size)
{
if(l->size<mt)
{
mt=l->size; min=l; t=1;
}
}
l=l->next;
}
if(mt!=256) ﻩ ﻩ ﻩ ﻩ//找到第一个满足要求得空闲块
{
busy j;
j=(busy)malloc(sizeof(busyspace)); ﻩﻩ//申请分配用于存放进程得内存空间
j->from=min->from; ﻩﻩ
//将第一个满足要求得空闲块(min)得首地址赋给j
for(int i=0;i<10;i++)
{
j->r、name[i]=D、name[i];
}
j->r、size=D、size;
while(b->next) ﻩﻩﻩ
//按从小到大得顺序查找新进程在已分配区中得位置
{ if(b->next->from<j->from)
b=b->next; else
break;
}
j->next=b->next;
b->next=j; ﻩ //将所输入得进程插入进程链
min->from=min->from+D、size; ﻩﻩ //改变该空闲块得起始地址
min->size=min->size-D、size; ﻩ ﻩ //改变该空闲块得剩余大小
}
return t;
}
最坏适应算法
为了克服最佳适应算法把空闲区切割得太小得缺点,人们提出了一种最坏适应算法,即每次分配时,总就是将最大得空闲区切去一部分分配给请求者,剩余得部分仍就是一个较大得空闲区。避免了空闲区越分越小得问题。
要求空闲区按容量递减得顺序排列。
分配:进程申请存储区时,检查空闲区表(链)得第一个空闲区得大小就是否满足要求,若不满足则令进程等待;若满足则从该空闲区中分配一部分存储区给用户,剩下得部分仍作为空闲区。
最坏适应算法
int WF()
{
int t=0;
readyque D;
printf“"请输入进程名:\”");
scanf“"%”",D、name);
printf“"输入进程申请空间大小:\”");
scanf“"%”",&D、size); //输入进程申请得空间大小
idly l=Is;//l指向空闲链表ls头
idly min=NULL;
int mt=0;
busy b=Bs;ﻩ ﻩﻩ ﻩ //b指向已分配链表Bs头
//找到空闲分区中大小满足进程得请求且尺寸最大得结点
while(l)
{
if(D、size<=l->size)
//判断进程所申请得大小就是否小于空闲区得各结点大小
{
if(l->size>mt)
{
mt=l->size;
min=l;//min指向空闲区中尺寸最大得结点
t=1;
}
}
l=l->next; ﻩ ﻩﻩﻩﻩﻩ//l指向空闲链表下一个结点
}
if(mt!=0) ﻩ ﻩ ﻩﻩ //判断就是否找到了空闲区得满足结点
{
busy j;
j=(busy)malloc(sizeof(busyspace));
j->from=min->from;
for(int i=0;i<10;i++)
{
j->r、name[i]=D、name[i];
}
j->r、size=D、size;
while(b->next)ﻩ ﻩﻩﻩﻩ //寻找插入到已分配链表中得位置
{ if(b->next->from<j->from)
b=b->next; else
break;
}
//把此进程结点j插入到已分配链表中
j->next=b->next;
b->next=j;
//修改空闲链表得相应结点得参数
min->from=min->from+D、size;
min->size=min->size-D、size;
}
return t;
}
可变分区得回收
当某个进程释放某存储区时,系统首先检查释放区就是否与系统中得空闲区相邻若相邻则把释放区合并到相邻得空闲区去,否则把释放区作为一个空闲区插入到空闲表得适当位置。
释放区与空闲区相邻得四种情况。
(1) 释放区与前空闲区相邻:把释放区与前空闲区合并到一个空闲区。其首址仍为前空闲区首址,大小为释放区大小与空闲区大小之与。
(2) 释放区与后空闲区相邻:则把释放区合并到后空闲区,其首地址为释放区首地址,大小为二者之与。
(3) 释放区与前后两空闲区相邻:这三个区合为一个空闲区,首地址为前空闲区首址,大小为这三个空闲区之与,并取消后空闲区表目。
(4) 释放区不与任何空闲区相邻:将释放区作为一个空闲区,将其大小与首址插入到空闲区表得适当位置。
回收内存算法
int recover()
{
readyque D;
printf“"请输入想要回收得进程名\”");
scanf“"%”",D、name);
busy b=Bs;
idly l=Is;
while(b->next) ﻩﻩ //查找输入得进程名就是否在已分配链表中
{
bool yo=1;
for(int i=0;i<10;i++)
{
if(b->next->r、name[i]==D、name[i]) yo=yo*1;
else yo=0;
}
//如果在已分配链表中则释放该结点所占空间
if(yo)
{
int t=b->next->from;
int ts=b->next->r、size;
while(l)
{ if(l->from>t+ts) ﻩ //所回收进程与空闲结点上下都不邻接
{
idly tl;
tl=(idly)malloc(sizeof(idlyspace));
tl->from=t;
tl->size=ts;
tl->next=l;
Is=tl;
break;
}
if(l->from==t+ts) ﻩ ﻩ ﻩ//所回收进程与空闲结点下邻接 {
l->from=t;
l->size=l->size+ts;
busy tb=b->next;
b->next=b->next->next;
free(tb);
return 1;
}
if(l->from+l->size<t)ﻩﻩ ﻩ //所回收进程与空闲结点上下都不邻接 {
idly tl;
tl=(idly)malloc(sizeof(idlyspace));
tl->from=t;
tl->size=ts;
tl->next=l->next;
l->next=tl;
break;
展开阅读全文