分配与回收
实验报告二主存空间的分配和回收

if(strcmp(PName,"OS")==0)
{ printf("ERROR!");
return;
}
while((strcmp(temp->proID,PName)!=0||temp->flag==1)&&temp)
temp=temp->next;
四、程序中使用的数据结构及符号说明
结构1:
typedef struct freeTable
{
char proID[6];
int startAddr; /*空闲区起始地址*/
int length; /*空闲区长度,单位为字节*/
int flag; /*空闲区表登记栏标志,用"0"表示空表项,用"1"表示未分配*/
freeNode=freeNode->next;
}
getchar();
break;
default:printf("没有该选项\n");
}/*case*/
}/*while*/
}/*main()*/
六、运行调试结果
初始界面:
分配主存,五个作业名:P1、P2、P3、P4、P5
显示主存使用情况:
回收主存P2:
if(front->flag==1&&rear->flag==1)
/* 上邻空闲区,下邻空闲区,三项合并*/
{
front->length=front->length+rear->length+temp->length;
虚拟机内存管理:分配与回收策略

虚拟机内存管理:分配与回收策略虚拟机内存管理是操作系统中的一个重要领域。
在计算机系统中,内存是一项有限的资源,而操作系统需要合理地分配和回收内存,以满足不同应用程序的需求。
本文将探讨虚拟机内存管理中的分配与回收策略。
一、内存分配策略在虚拟机中,内存的分配通常是在进程创建时进行的。
操作系统需要将一块连续的内存空间分配给该进程,并且记录该进程的内存边界。
常见的内存分配策略有以下几种。
首次适应算法(First Fit):该算法将内存空间划分为若干块,从头开始查找第一个足够大的空闲块来进行分配。
这种算法的优点是简单高效,但容易造成内存碎片。
最佳适应算法(Best Fit):该算法从所有空闲块中找到最小的适配块进行分配。
相比首次适应算法,最佳适应算法能更好地利用内存空间,减少碎片的产生,但分配效率较低。
循环首次适应算法(Next Fit):该算法与首次适应算法类似,但是从上一次分配位置开始循环查找。
这样可以减少搜索的时间,提高分配效率。
内存分配时还需要考虑其他因素,如内存的对齐方式和分页机制。
对齐方式可以提高访问速度,而分页机制可以更好地管理内存空间。
二、内存回收策略内存回收是指在程序执行过程中,当某些进程不再使用内存时,将其释放给操作系统重新分配。
常见的内存回收策略有以下几种。
引用计数法:该方法记录每个对象被引用的次数,当引用次数为0时,即可将该对象回收。
但是引用计数法无法解决循环引用的问题,容易造成内存泄漏。
标记-清除算法:该算法通过标记未被引用的内存块,然后清除这些块来回收内存。
这个算法可以解决循环引用的问题,但会产生内存碎片。
分代回收算法:该算法将内存分为多个代,根据对象的存活时间将其分配到不同的代中。
年轻代的回收频率较高,老年代的回收频率较低。
这样可以更有效地进行内存回收。
写时复制(Copy-on-write):该技术将内存分为读写两个副本,在写操作时才会进行复制。
这样可以减少内存拷贝的开销,提高性能。
用首次适应算法实现内存分配与回收

用首次适应算法实现内存分配与回收首次适应算法(First Fit)是一种常用的内存分配算法,它将内存分为若干个大小相等的块,并按顺序进行分配。
当有一个进程请求内存时,首次适应算法从头开始,找到第一个大小能够满足这个进程需要的空闲块,将其分配给该进程。
以下是使用首次适应算法实现内存分配与回收的一种简单示例:1.假设整个内存大小为M字节,每个块的大小为N字节,内存被分为M/N个块。
2. 定义一个长度为(M/N)的布尔数组block,表示每个块的分配状态,初始时所有元素都为false,表示空闲状态。
3. 当一个进程请求分配S字节的内存时,首次适应算法从第一个块开始遍历数组block,直到找到一个大小大于等于S的空闲块。
4. 如果找到了合适的空闲块,将该块标记为已分配(设置为true),并返回该块的起始地址;否则,返回分配失败的标识。
5. 当一个进程释放已分配的内存时,可以根据该内存的起始地址计算出对应的块索引,将对应的block元素设置为false,表示该块变为空闲状态。
以下是一个简单的C++代码示例,演示了使用首次适应算法进行内存分配与回收的实现:```cpp#include <iostream>using namespace std;const int M = 1000; // 总内存大小const int N = 100; // 块大小bool block[M/N] = { false }; // 内存块分配状态//首次适应内存分配算法int allocateMemory(int size)int numBlocks = M / N; // 块数量int numNeeded = size / N;if (size % N != 0)numNeeded++;}for (int i = 0; i < numBlocks; i++)bool found = true;for (int j = i; j < i + numNeeded; j++)if (j >= numBlocks , block[j] == true)found = false;break;}}if (found)for (int j = i; j < i + numNeeded; j++)block[j] = true;}return i * N;}}return -1; // 分配失败//内存回收void deallocateMemory(int startAddr, int size)int startIndex = startAddr / N;int numBlocks = size / N;if (size % N != 0)numBlocks++;}for (int i = startIndex; i < startIndex + numBlocks; i++) block[i] = false;}int maiint size1 = 200; // 请求200字节内存int size2 = 300; // 请求300字节内存int addr1 = allocateMemory(size1);int addr2 = allocateMemory(size2);if (addr1 != -1)cout << "分配内存成功,起始地址:" << addr1 << endl; } elsecout << "分配内存失败" << endl;}if (addr2 != -1)cout << "分配内存成功,起始地址:" << addr2 << endl; } elsecout << "分配内存失败" << endl;}deallocateMemory(addr1, size1);deallocateMemory(addr2, size2);return 0;```这段代码实现了一个简单的内存分配与回收示例。
虚拟机内存管理:分配与回收策略(一)

虚拟机内存管理:分配与回收策略作为计算机科学中的重要概念之一,虚拟机内存管理在现代计算中发挥着关键作用。
它不仅关乎到计算机系统的性能与效率,还影响着用户体验和软件开发的质量。
本文将介绍虚拟机内存管理的分配与回收策略,并探讨它们对系统性能的影响。
一、内存分配策略在虚拟机内存管理中,内存分配策略决定了如何将有限的内存资源分配给不同的程序和应用。
下面将介绍几种常见的内存分配策略。
1. 固定分区分配固定分区分配是一种较为简单直接的内存分配策略。
它将内存划分为固定大小的分区,每个分区都被分配给一个程序或应用。
这种策略的优点是实现简单、分配效率较高。
然而,由于每个程序都需要有固定大小的分区,导致了内存碎片问题。
当分区大小与程序需求不匹配时,将造成内存浪费或无法满足需要。
2. 动态分区分配为解决固定分区分配中的内存碎片问题,动态分区分配策略应运而生。
它允许程序在运行时根据需要动态分配内存空间。
常见的动态分区分配算法有“首次适应算法”、“循环首次适应算法”等。
这些算法通过优化内存分配过程,减少内存碎片,提高内存利用率。
3. 页表分配为实现虚拟内存的概念,页表分配策略被广泛应用于现代计算机系统中。
它将物理内存划分为固定大小的物理页框,并将虚拟内存划分为固定大小的虚拟页。
通过页表,将虚拟页映射到物理页框上。
这种策略实现了虚拟内存与物理内存的分离,使得程序能够运行在比实际物理内存更大的地址空间上。
二、内存回收策略除了分配内存,虚拟机内存管理还需要处理内存的回收。
及时回收不再使用的内存,释放给其他应用或程序使用,对于系统的正常运行至关重要。
下面将介绍几种常见的内存回收策略。
1. 垃圾回收垃圾回收是一种主动管理内存的策略。
它通过自动识别和回收不再使用的内存对象,释放它们所占用的内存空间。
垃圾回收策略通过算法实现,如引用计数、标记-清除、复制算法等。
这些算法帮助虚拟机定期检测并回收无用的内存对象,减少内存泄漏和资源浪费问题。
用位示图管理磁盘空间的分配与回收

课程设计报告( 2016--2017年度第二学期)课程名称:操作系统实验课设题目: 用位示图管理磁盘空间的分配与回收院系:控制与计算机工程学院班级:信安1401姓名:黄竞昶指导教师:贾静平设计周数: 一周成绩:2015年7月9 日一、需求分析要求打印或显示程序运行前和运行后的位示图,以及分配和回收磁盘的物理地址过程。
(1)假定现有一个磁盘组,共40个柱面。
每个柱面4个磁道,每个磁道又划分成4个物理记录。
磁盘的空间使用情况用位示图表示。
位示图用若干个字构成,每一位对应一个磁盘块。
1表示占用,0表示空闲。
为了简单,假定字长为16位,其位示图如图9—1所示。
系统设一个变量S,记录磁盘(2)申请一个磁盘块时,由磁盘块分配程序查位示图,找出一个为0的位,并计算磁盘的物理地址(即求出柱面号、磁道号(也即磁头号)和扇区号)。
由位示图计算磁盘的相对块号的公式如下:相对块号一字号×16+位号之后再将相对块号转换成磁盘的物理地址:由于一个柱面包含的扇区数=每柱面的磁道数×每磁道的扇区数=4×4=16,故柱面号=相对块号/16的商,即柱面号=字号磁道号=(相对块号/16的余数)/4的商,即(位号/4)的商物理块号=(相对块号/16的余数)/4的余数,即(位号/4)的余数(3)当释放一个相对物理块时,运行回收程序,计算该块在位示图中的位置,再把相应位置0。
计算公式如下:先由磁盘地址计算相对块号:相对块号=柱面号×16+磁道号×4+物理块号再计算字号和位号:字号=相对块号/16的商,也即字号=柱面号位号=磁道号×物理块数/每磁道+物理块号(4)按照用户要求,申请分配一系列磁盘块,运行分配程序,完成分配。
然后将分配的相对块号返回用户,并将相对块号转换成磁盘绝对地址,再显示系统各表和用户已分配的情况。
(5)设计一个回收算法,将上述已分配给用户的各盘块释放。
并显示系统各表。
linux主存空间分配与回收

在Linux操作系统中,主存空间(内存)的分配和回收是由内核管理的。
当应用程序或系统需要更多的内存时,它们会向内核请求,内核会根据可用内存的情况来分配内存。
同样,当应用程序或系统不再需要某块内存时,它们会将其释放给内核,内核会将其回收以供将来使用。
1. 内存分配:
在Linux中,当一个进程需要更多的内存时,它会调用`malloc()`或`alloc()`等函数。
这些函数会向内核发送请求,要求分配一块指定的内存大小。
内核会查看当前可用内存的情况,并根据需要分配一块内存。
内核分配内存的过程包括以下几个步骤:
* 找到可用的物理内存页框。
* 将页框标记为已分配状态。
* 更新内存管理数据结构。
* 将页框地址返回给进程。
2. 内存回收:
当一个进程不再需要某块内存时,它会调用`free()`或`release()`等函数来释放该内存。
这些函数会将该内存标记为未分配状态,并通知内核回收该内存。
内核回收内存的过程包括以下几个步骤:
* 标记该页框为未分配状态。
* 更新内存管理数据结构。
* 如果该页框中有数据,则将其写回到磁盘或其他存储设备中。
* 将该页框标记为可用状态,以供将来使用。
需要注意的是,Linux采用了先进的内存管理技术,如分页和段页式管理,以及虚拟内存技术等,使得内存的分配和回收更加高效和灵活。
同时,Linux还具有强大的内存监控和管理工具,如`top`、`htop`、`free`等,可以帮助管理员监控和管理系统的内存使用情况。
存储器管理——动态分区的分配与回收
计算机与信息工程系实验报告
班级计算机
1001
姓名李双贺时间2011.11.09 地点A504
实验名称存储器管理——动态分区的分配与回收
实验目的
目的是在学习操作系统理论知识的基础上,对操作系统整体的一个模拟。
研究计算机操作系统的基本原理和算法,掌握操作系统的存储器管理的首次适应算法、循环首次适应算法、最佳适应算法的基本原理和算法。
提高运用操作系统知识和解决实际问题的能力;并且锻炼自己的编程能力、创新能力以及开发软件的能力。
使学生掌握基本的原理和方法,最后达到对完整系统的理解。
实验内容
内存调度策略可采用首次适应算法、循环首次适应算法和最佳适应法等,并对各种算法进行性能比较。
为了实现分区分配,系统中必须配置相应的数据结构,用来描述空闲区和已分配区的情况,为分配提供依据。
常用的数据结构有两种形式:空闲分区表和空闲分区链。
为把一个新作业装入内存,须按照一定的算法,从空闲分区表或空闲分区链中选出一个分区分配给该作业。
实验结果。
存储管理动态分区分配及回收算法
存储管理动态分区分配及回收算法存储管理是操作系统中非常重要的一部分,它负责对计算机系统的内存进行有效的分配和回收。
动态分区分配及回收算法是其中的一种方法,本文将详细介绍该算法的原理和实现。
动态分区分配及回收算法是一种将内存空间划分为若干个动态分区的算法。
当新的作业请求空间时,系统会根据作业的大小来分配一个合适大小的分区,使得作业可以存储在其中。
当作业执行完毕后,该分区又可以被回收,用于存储新的作业。
动态分区分配及回收算法包括以下几个步骤:1.初始分配:当系统启动时,将整个内存空间划分为一个初始分区,该分区可以容纳整个作业。
这个分区是一个连续的内存块,其大小与初始内存大小相同。
2.漏洞表管理:系统会维护一个漏洞表,用于记录所有的可用分区的大小和位置。
当一个分区被占用时,会从漏洞表中删除该分区,并将剩余的空间标记为可用。
3.分区分配:当一个作业请求空间时,系统会根据作业的大小,在漏洞表中查找一个合适大小的分区。
通常有以下几种分配策略:- 首次适应(First Fit): 从漏洞表中找到第一个满足作业大小的分区。
这种策略简单快速,但可能会导致内存碎片的产生。
- 最佳适应(Best Fit): 从漏洞表中找到最小的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
- 最差适应(Worst Fit): 从漏洞表中找到最大的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
4.分区回收:当一个作业执行完毕后,系统会将该分区标记为可用,并更新漏洞表。
如果相邻的可用分区也是可合并的,系统会将它们合并成一个更大的分区。
总结来说,动态分区分配及回收算法是一种对计算机系统内存进行有效分配和回收的方法。
通过合理的分配策略和回收机制,可以充分利用内存资源,提高系统性能。
然而,如何处理内存碎片问题以及选择合适的分配策略是需要仔细考虑的问题。
虚拟机内存管理:分配与回收策略(六)
虚拟机内存管理:分配与回收策略概述随着计算机技术的飞速发展,虚拟化技术在数据中心中的应用日益广泛。
虚拟机是一种将物理服务器划分为多个独立虚拟环境的技术,它通过虚拟机监控程序(VMM)来管理物理资源。
其中,内存管理是虚拟化技术中的重要组成部分。
本文将着重讨论虚拟机内存管理中的分配与回收策略。
虚拟机内存分配策略虚拟机内存分配策略目的在于高效地利用有限的物理内存资源,并满足虚拟机对内存的需求。
常见的内存分配策略包括固定分配、按需分配和动态分配。
固定分配是指将一定数量的物理内存资源预先分配给虚拟机。
这种分配策略适用于长时间运行的虚拟机,能够在一定程度上保障虚拟机的性能稳定性。
然而,固定分配策略存在一定浪费,因为虚拟机可能在某些时候没有充分利用分配的内存。
按需分配是动态分配内存的一种策略,只有虚拟机在运行过程中需要时才分配内存。
这种分配策略可以灵活应对虚拟机的内存需求,避免了过度分配的浪费。
然而,按需分配也存在一定的问题,当多个虚拟机同时需要内存时,可能会导致内存不足的情况。
动态分配是根据虚拟机的内存使用情况动态调整内存资源。
虚拟机可以根据负载情况自动请求更多内存或释放多余的内存。
这种分配策略可以更好地适应虚拟机工作负载的变化,提高内存资源的利用率。
但是,动态分配策略也需要较高的管理开销和额外的资源投入。
虚拟机内存回收策略虚拟机内存回收是指通过合理的回收方式释放被虚拟机占用但实际上闲置的内存资源。
常见的内存回收策略包括页面换出、压缩和抢占。
页面换出是将虚拟机内存中的某些页面写回到磁盘或其他非易失性存储介质上,以释放内存空间。
当虚拟机需要访问换出的页面时,再将其重新读入内存。
页面换出策略可以有效释放内存,但在换出和读入过程中会引入一定的延迟。
压缩是一种通过重新组织虚拟机内存内容来释放内存的策略。
压缩方法可以将闲置部分内存进行合并,提高内存的利用率。
这种策略通常适用于虚拟机内存中存在较多不活跃对象的情况下。
抢占是通过暂停或迁移某个虚拟机,将其占用的内存资源分配给其他需要的虚拟机。
伙伴系统内存分配与回收的原理
伙伴系统内存分配与回收的原理一、引言随着计算机应用的广泛推广,内存管理成为了一个重要且不可忽视的问题。
在操作系统中,伙伴系统是一种常用的内存分配和回收算法。
本文将深入探讨伙伴系统的原理、应用以及优缺点。
二、伙伴系统的基本概念伙伴系统是一种基于二进制块划分的内存管理机制,它将内存划分为一系列大小相等的块,并使用分配表来记录块的使用情况。
2.1 分配表分配表是伙伴系统的核心,它采用一棵二叉树结构表示内存块的分配情况。
每个内存块对应二叉树中的一个节点,节点的左子节点表示当前内存块被划分为两个较小的伙伴块,右子节点表示当前内存块仍然被占用。
2.2 内存块的分配和回收在伙伴系统中,内存分配和回收的过程如下:2.2.1 内存分配1.当一个进程请求分配一块指定大小的内存时,伙伴系统会根据需求的大小找到一个合适的块。
2.如果该块的大小正好等于需求大小,则将该块分配给进程。
3.否则,将该块分裂为两个较小的伙伴块,并标记其中一个为已分配,另一个为未分配。
然后重复步骤1和2,直到找到适合大小的块。
2.2.2 内存回收1.当一个进程释放一块内存时,伙伴系统会合并该块与其伙伴块,并检查是否能够合并成较大的块。
2.如果可以合并,则继续合并,直到无法再合并为止。
3.最后,将合并后的块标记为空闲状态。
三、伙伴系统的优缺点伙伴系统作为一种常用的内存管理算法,具有以下优点和缺点。
3.1 优点3.1.1 内部碎片少伙伴系统通过将内存划分为大小相等的块,可以最大限度地避免内部碎片问题。
每个块的大小都是2的幂次,因此块的大小与进程的内存需求能够很好地匹配。
3.1.2 分配与回收效率高伙伴系统通过二叉树结构来表示内存块的分配情况,从而快速定位合适的块。
此外,内存的分配和回收操作只需要进行块的合并和划分,时间复杂度为O(logn),效率较高。
3.2 缺点3.2.1 外部碎片问题伙伴系统虽然能够有效地避免内部碎片,但无法解决外部碎片问题。
在连续分配和回收的情况下,大量的空闲块可能出现在已分配块的周围,导致外部碎片的产生。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
// 文件名: osmd.cpp// 作者: 宋梦国// 功能描述: 操作系统内存分区分配算法演示// 开发日志: Creat on 02-06-29 15:24// Modefy on 02-07-24 19:39// Modefy on 05-02-10 实现在DEV-C++下编译;bf算法有bug! // Modefy on 06-11-10 1.修正bf算法bug// 2.增加测试数据// 3.拟增加从文件输入测试数据功能// 测用数据:// 1.测试最佳适应算法// 作业 begint keept size// A 0 4 200// B 1 6 300// C 4 1 70// D 5 4 250// 2.测试适应算法// 作业 begint keept size// A 0 4 100// B 1 6 100// C 2 2 150// D 3 5 120// E 3 2 40// F 4 2 40// G 5 3 30// H 5 2 30///////////////////////////////////////////////////using namespace std;// HDR FIELS //////////////////////////////////////#include <iostream>#include <stdlib.h>#include <stdio.h>#include <conio.h>#include <windows.h>// CONST //////////////////////////////////////////#define MMAX 600// TYPE ///////////////////////////////////////////typedef struct jobstr //作业信息{ int begint;//作业开始时间int keept;//作业持续时间int endt;//作业结束时间int size;//作业申请空间大小}jobstr;typedef struct lnode //内存映像链表结点{ int h; //内存块起始地址int t; //内存块结束地址int tag;//内存块标记struct lnode *next;//下一结点地址}lnode;// GLOBAL /////////////////////////////////////////int st=-1;//当前时间int latest=-1;//最近的int latestime=latest;int latestid=-1;jobstr job[30]; //作业信息映像int jobcount;//作业个数lnode *ml=NULL,*bfp=NULL,*rffp=NULL;//内存映象链表头指针,// 屏幕输出定位 /////////////////////////////////////////void gotoxy(int x, int y)// DEV-C++库函数无该函数{COORD c;c.X = x - 1;c.Y = y - 1;SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);}// 屏幕输出着色 /////////////////////////////////////////void textcolor (int color)// DEV-C++库函数无该函数{SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), color ); }// 整数输入(只接受数字) /////////////////////////////////////////int inputnum(int x, int y){char w=' ';int flag=0,p=0;do{cout << " ";gotoxy(x,y); w=cin.get(); //从屏幕坐标为(x,y)位置输入字符if('\n' != w ){if(1==flag) continue;else if(w <'0' || w > '9')flag=1;else{p=p*10+int(w)-48;continue;}}else{ if(1==flag) {flag=0;p=0;continue;}else break;}}while(1);return (p);}// 作业信息输入 /////////////////////////////////////////void inputjob(){int i,k;jobcount=0;//重新输入一批作业时,作业总数清零system("CLS");textcolor(12);while(0 == jobcount ||15 < jobcount)//输入0到15之间的整数{gotoxy(3,3);cout << "请输入作业个数(15>=jobcount>0): ";jobcount = inputnum(34,3);//cin.get();}for(i=0;i<jobcount;i++){system("CLS");gotoxy(5,4);textcolor(10);cout <<"输入第"<<i+1<<"个作业"<<char(i+65)<<"的相关信息:";textcolor(15);job[15+i].begint=-1;while(0 > job[15+i].begint ||15 < job[15+i].begint){gotoxy(7,5);cout <<char(i+65) <<"作业开始时间(25>=t>0): "; job[15+i].begint = inputnum(32,5);//cin.get();}job[15+i].keept=-1;while(0 > job[15+i].keept ||15 < job[15+i].keept){gotoxy(7,6);cout <<char(i+65) <<"作业持续时间(25>=t>0): ";job[15+i].keept = inputnum(32,6);//cin.get();}job[15+i].size=-1;while(0 > job[15+i].size ||600 < job[15+i].size){gotoxy(7,7);cout <<char(i+65) <<"作业申请内存空间大小(600>size>0): ";job[15+i].size = inputnum(42,7);//cin.get();}job[15+i].endt=job[15+i].begint+job[15+i].keept;if(latest<job[15+i].endt){//cout<< job[15+i]latest=job[15+i].endt;latestime=latest;/////////////////////////////latestid=i;}job[i].begint=job[15+i].begint;job[i].keept=job[15+i].keept;job[i].size=job[15+i].size;job[i].endt=job[15+i].endt;}}// 作业信息输出 //////////////////////////////////////void outputjob(){int i;for(i=0;i<jobcount;i++){textcolor(i+1==8 ? 14:i+1);gotoxy(1,i+6);printf(" %c%5d%5d%5d\n",i+65,job[i].begint,job[i].endt,job[i].size);}textcolor(15);}// 屏幕输出格式 /////////////////////////////////////////void fm(){int i;system("CLS");;textcolor(15);gotoxy(21,1);cout <<"内存动态分区分配方法演示";gotoxy(1,2);for(i=1;i<=80;i++)cout <<"=";gotoxy(1,3);cout <<" JOB INFO PARTITION TABLE MEMORY STATE"; gotoxy(1,4);cout <<" ID START END SIZE HEAD TAIL TAG";gotoxy(1,5);for(i=1;i<=80;i++)cout <<"-";for(i=3;i<=20;i++){gotoxy(20,i);cout <<"|";gotoxy(38,i);cout <<"|";}gotoxy(1,i);for(i=1;i<=80;i++)cout <<"=";}// 内存映像链表初始化 /////////////////////////////////////////void initml(){ml=new lnode;ml->next=NULL;ml->h=1;//内存块起始地址ml->t=MMAX;//内存块结束地址ml->tag='*';//内存块标记}// 内存不足处理 /////////////////////////////////////////void mnoenough(int i){int j;job[i].begint++;job[i].endt++;if(i==latestid)latest++;for(j=0;j<jobcount;j++){if(latest<=job[i].endt){latest=job[i].endt;latestid=i;}}gotoxy(1,24);textcolor(12);cout <<"内存不足!!!作业";gotoxy(16+i,24);textcolor(12);cout<<char(i+65)<<"被迫延迟1秒响应!!!";textcolor(15); }#include<stdio.h>#include<iostream.h>#include<string.h>#include<iomanip.h>const int MAXJOB=100;//定义表最大记录数typedef struct node{int start;int length;char tag[20];}job;job frees[MAXJOB];//定义空闲区表int free_quantity;job occupys[MAXJOB];//定义已分配区表int occupy_quantity;//初始化函数void initial(int a){occupys[0].start=20;occupys[0].length=32;strcpy(occupys[0].tag,"A");occupys[1].start=52;occupys[1].length=20;strcpy(occupys[1].tag,"B");occupys[2].start=98;occupys[2].length=40;strcpy(occupys[2].tag,"C");occupys[3].start=148;occupys[3].length=22;strcpy(occupys[3].tag,"D");if(a==1){frees[0].start=72;frees[0].length=26; strcpy(frees[0].tag,"free"); frees[1].start=138;frees[1].length=10; strcpy(frees[1].tag,"free"); frees[2].start=170;frees[2].length=86; strcpy(frees[2].tag,"free"); free_quantity=3;occupy_quantity=4;}if(a==2){frees[0].start=138;frees[0].length=10; strcpy(frees[0].tag,"free"); frees[1].start=72;frees[1].length=20; strcpy(frees[1].tag,"free"); frees[2].start=170;frees[2].length=86; strcpy(frees[2].tag,"free"); free_quantity=3;occupy_quantity=4;}if(a==3){frees[0].start=170;frees[0].length=86; strcpy(frees[0].tag,"free"); frees[1].start=72;frees[1].length=26; strcpy(frees[1].tag,"free"); frees[2].start=138;frees[2].length=10; strcpy(frees[2].tag,"free"); free_quantity=3;occupy_quantity=4;}}//显示函数void view(){int i;cout<<endl<<"----------------------------------------------------------"<<endl; cout<<"当前空闲表:"<<endl;cout<<"起始地址长度状态"<<endl;for(i=0;i<free_quantity;i++){cout.setf(2);cout.width(12);cout<<frees[i].start;cout.width(10);cout<<frees[i].length;cout.width(8);cout<<frees[i].tag<<endl;}cout<<endl<<"----------------------------------------------------------"<<endl; cout<<"当前已分配表:"<<endl;cout<<"起始地址长度占用作业名"<<endl;for(i=0;i<occupy_quantity;i++){cout.setf(2);cout.width(12);cout<<occupys[i].start;cout.width(10);cout<<occupys[i].length;cout.width(8);cout<<occupys[i].tag<<endl;}}//最先适应分配算法void earliest(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length){flag=1;}}if(flag==0){cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl; }else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){t=1;}i++;}i--;occupys[occupy_quantity].start=frees[i].start;strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//最优适应分配算法void excellent(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length){flag=1;}}if(flag==0){cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl; }else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){t=1;}i++;}i--;for(j=0;j<free_quantity;j++){if((frees[j].length>=job_length)&&(frees[j].length<frees[i].length)){i=j;}}occupys[occupy_quantity].start=frees[i].start;strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;}else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//最坏适应算法void worst(){char job_name[20];int job_length;int i,j,flag,t;cout<<"请输入新申请内存空间的作业名和空间大小:";cin>>job_name;cin>>job_length;flag=0;for(i=0;i<free_quantity;i++){if(frees[i].length>=job_length){flag=1;}}if(flag==0){cout<<endl<<"Sorry,当前没有能满足你申请长度的空闲内存,请稍候再试"<<endl; }else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){t=1;}i++;}i--;for(j=0;j<free_quantity;j++){if((frees[j].length>=job_length)&&(frees[j].length>frees[i].length)){i=j;}}occupys[occupy_quantity].start=frees[i].start;strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].start+=job_length;frees[i].length-=job_length;else{for(j=i;j<free_quantity-1;j++){frees[j]=frees[j+1];}free_quantity--;cout<<"内存空间成功:)"<<endl;}}}//撤消作业void finished(){char job_name[20];int i,j,flag,p=0;int start;int length;cout<<"请输入要撤消的作业名:";cin>>job_name;flag=-1;for(i=0;i<occupy_quantity;i++){if(!strcmp(occupys[i].tag,job_name)){flag=i;start=occupys[i].start;length=occupys[i].length;}}if(flag==-1){cout<<"没有这个作业名"<<endl;}else{//加入空闲表for(i=0;i<free_quantity;i++){if((frees[i].start+frees[i].length)==start){if(((i+1)<free_quantity)&&(frees[i+1].start==start+length)){ frees[i].length=frees[i].length+frees[i+1].length+length;for(j=i+1;j<free_quantity;j++){frees[j]=frees[j+1];}free_quantity--;p=1;else{frees[i].length+=length;p=1;}}if(frees[i].start==(start+length)){frees[i].start=start;frees[i].length+=length;p=1;}}if(p==0){frees[free_quantity].start=start;frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;i<occupy_quantity;i++){occupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int t=1;int chioce=0;int flag=1;int a;state:cout<<"1.最先适应算法,2.最优适应算法3.最差适应算法"; cin>>a;initial(a);while(flag==1){cout<<endl<<endl<<"================================= ========================"<<endl;cout<<" 可变分区存储管理模拟系统"<<endl;cout<<"=========================================== =============="<<endl;cout<<" 1.申请空间2.撤消作业3.显示空闲表和分配表0.退出"<<endl;cout<<"请选择:";cin>>chioce;switch(chioce){case 1:switch(a){case 1: earliest(); break;case 2: excellent();break;case 3: worst();break;}break;case 2:finished();break;case 3:view();break;case 0:goto state;break;default:cout<<"选择错误!"<<endl;}}}。