模拟设计页式存储管理的分配与回收
存储管理——动态分区分配回收算法的模拟
齐齐哈尔大学操作系统课程综合实践题目:存储管理——动态分区分配/回收算法的模拟班级:0姓名:0学号:0指导教师:02011年 12 月综合实践评分表班级0 姓名0 指导教师0 题目:存储管理---动态分区分配/回收算法的模拟评分标准评分标准分数权重评分的依据得分A C选题10 选题符合大纲要求,题目较新颖,工作量大选题基本符合大纲要求,工作量适中工作态度10 态度端正,能主动认真完成各个环节的工作,不迟到早退,出勤好。
能够完成各环节基本工作,出勤较好。
存储结构、算法描述20能正确选择存储结构,定义准确,算法流程图或类C语言描述的算法准确无误能正确选择存储结构,算法流程图或类C语言描述的算法基本准确独立解决问题的能力10具有独立分析、解决问题能力,有一定的创造性,能够独立完成软件的设计与调试工作,程序结构清晰,逻辑严谨,功能完善。
有一定的分析、解决问题能力。
能够在老师指导下完成软件的设计与调试工作,程序功能较完善。
答辨问题回答20 能准确回答老师提出的问题能基本准确回答老师提出的问题程序运行情况10 程序运行正确、界面清晰,测试数据设计合理。
程序运行正确、界面较清晰,能给出合适的测试数据。
综合实践报告20 格式规范,层次清晰,设计思想明确,解决问题方法合理,体会深刻。
格式较规范,设计思想基本明确,解决问题方法较合理。
总分指导教师(签字):注:介于A和C之间为B级,低于C为D级和E级。
按各项指标打分后,总分在90~100为优,80~89为良,70~79为中,60~69为及格,60分以下为不及格。
存储管理---动态分区分配/回收算法的模拟摘要:主存的分配和回收的实现是与住存储器的管理方式有关的。
解决多进程如何共享主存空间的问题。
当进程运行完时将进程所占的主存空间归还给系统。
可变分区存储管理方式,分区分配中所用的数据就够采用空闲分区说明表和空闲分区链表来进行。
关键字:内存分配,空闲分区表,进程申请队列一、【实践目的】:1、熟悉主存分配与回收2、理解在不同的存储管理方式,如何实现主存空间的分配与回收3、掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。
存储管理动态分区分配及回收算法
before=head2; after=head2->next; while(after) { if(after->adr==back2->adr+back2->size) {//和后边空闲区合并
void print(char choice)//输出空闲区队列信息
-9-
{ Node *p;
if(choice=='f'||choice=='F') p=head1->next;
else p=head2->next;
if(p) { printf("\n空闲区队列的情况为:\n");
-4-
if(back1->adr==before->adr+before->size) {//和前边分区合并 before->size+=back1->size; before->next=back1->next; free(back1); } else if(after&&back1->adr+back1->size==after->adr) {//和后边分区合并 back1->size+=after->size; back1->next=after->next; back1->id=after->id; free(after); after=back1; } printf("\t首先分配算法回收内存成功!!!\n"); } else printf("\t首先分配算法回收内存失败!!!\n");
操作系统课程设计-模拟设计页式存储管理的分配与回收范文
学号:28课程设计模拟设计页式存储管理的分题目配与回收学院计算机科学与技术专业计算机科学与技术班级XX姓名XX指导教师XXX2011年01月09日课程设计任务书学生姓名: XX 专业班级:计算机0902班指导教师: XXX 工作单位:计算机科学与技术学院题目: 模拟设计页式存储管理的分配与回收初始条件:1.预备内容:阅读操作系统的内存管理章节内容,了解有关虚拟存储器、页式存储管理等概念,并体会页式管理内存的分配和回收过程。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.采用页式管理方案实施内存分配和回收。
能够处理以下的情形⑴能够输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
⑵要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收,撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日武汉理工大学《操作系统》课程设计说明书模拟设计页式存储管理的分配与回收1需求分析页式管理是一种内存空间存储管理的技术,页式管理分为静态页式管理和动态页式管理。
模拟内存分配与回收
实验三模拟内存分配与回收一、实验目的用高级语言编写和调试一个简单的内存分配与回收程序,模拟内存分配与回收的工作过程。
从而对内存分配与回收的实质内容和执行过程有比较深入的了解。
二、实验内容:任务:设计并实现一个简单的内存分配与回收程序在动态分区存储管理方式中,主要的操作是分配内存和回收内存。
1)分配内存程序采用某种分配算法,从空闲分区表中找到所需大小的分区。
设请求分区的大小为u.size,表中每个空闲分区的大小可表示为m.size。
若m.size- u.siz e ≤size(size是事先规定的不再切割的剩余分区的大小),说明多余部分太小,可不再切割,将整个分区分配给请求者;否则,从该分区中按请求的大小划分出一块内存空间分配出去,余下的部分仍然留在空闲分区表中。
然后,将分配区的起始地址返回给调用者。
如图3所示分配流程。
图3分配流程图2)回收内存当进程运行完毕释放内存时,程序根据回收区的首地址,从空闲区表中找到相应的插入点,此时,可能出现以下四种情况之一:①回收区与插入点的前一个空闲分区F1相邻接,见图4(a)。
此时应将回收区与插入点的前一个分区合并,不必为回收区分配新表项,而只需修改前一分区F1的大小。
②回收区与插入点的后一个空闲分区F2相邻接,见图4(b)。
此时也可将两分区合并,形成新的空闲分区,但用回收区的首地址作为新空闲区的首地址,大小为两者之和。
③回收区同时与插入点的前、后两个分区邻接,见图4(c)。
此时将三个分区合并,使用F1的表项和F1的首地址,取消F2的表项,大小为三者之和。
④回收区既不与F1相邻,又不与F2邻接,见图4(d)。
这时应为回收区单独建立一新表项,填写回收区的首地址和大小。
图4三、实验步骤(1) 打开VC,选择菜单项file->new,选择projects选项卡并建立一个名为" ry3"的win32 console applicatoin工程;创建时注意指定创建该工程的目录;(2) 在工程中创建源文件" ry3.cpp":选择菜单项project->add to project->files,在选择框中输入自己想要创建的文件名,这里是" ry3.cpp";在接下来询问是否创建新文件时回答"yes";然后通过Workspace->FileView->Source Files打开该文件,在其中编辑源文件并保存.(3) 通过调用菜单命令项build->build all进行编译连接,可以在指定的工程目录下得到debug-> sy3.exe程序,运行sy3.exe。
模拟实现操作系统内存分配与回收的算法背景概述
模拟实现操作系统内存分配与回收的算法背景概述随着计算机技术的不断发展,操作系统在计算机领域中的地位日益凸显。
操作系统作为计算机系统的核心,负责管理硬件资源,包括内存。
内存管理是操作系统的重要任务之一,它涉及到如何有效地分配和回收内存,以满足程序和系统的需求。
在操作系统中,内存管理通常通过虚拟内存和物理内存来实现。
虚拟内存通过地址空间映射将逻辑地址转换为物理地址,以便用户程序可以使用抽象的地址空间来访问物理内存。
物理内存则涉及到实际的物理存储设备的分配和管理。
操作系统中实现内存分配与回收的算法主要依赖于动态内存分配(Dynamic Memory Allocation)机制。
动态内存分配是一种在运行时分配和释放内存的方法,它是操作系统和许多高级编程语言的核心组件。
动态内存分配需要处理的问题包括内存碎片化、内存泄漏和溢出等。
为了解决这些问题,操作系统通常使用一种称为“分页”或“分段”的虚拟内存技术,将物理内存划分为固定大小的页或段,并在需要时进行页面置换或段替换。
本文将介绍一种模拟实现操作系统内存分配与回收的算法背景概述。
我们将从以下几个方面进行阐述:虚拟内存和物理内存的基本概念、动态内存分配机制、页面置换算法以及内存回收策略。
首先,虚拟内存和物理内存是操作系统中处理内存分配和回收的基本概念。
虚拟内存通过地址空间映射将程序的逻辑地址转换为物理地址,以实现抽象的地址空间访问物理内存。
这样可以隐藏物理内存的复杂性,并为程序员提供一种简单的方式来管理内存。
物理内存则是指实际的物理存储设备,如RAM、硬盘等。
动态内存分配是操作系统中实现内存管理的关键技术之一。
它允许程序在运行时请求和释放内存,避免了静态内存分配的局限性,如静态分配的内存不能重复使用,需要手动释放等。
动态内存分配通常使用数据结构如链表、哈希表等来跟踪分配的内存块,并使用垃圾收集机制来自动回收不再使用的内存。
页面置换算法是操作系统中实现动态内存分配的核心技术之一。
操作系统课程设计报告最佳适应算法模拟实现内存分配与回收
实验题目:最佳适应算法模拟实现内存分配与回收目录一、概述 (3)1.设计目的 (3)2.开发环境 (3)3.任务分配 (3)二、需求分析 (3)三、实验基本原理 (4)1.可变分区存储管理之最优适应分配算法的概念 (4)2.关于最优适应分配算法的一些基本原理 (4)四、数据结构设计 (4)1.内存块与作业块 (4)2.程序流程图 (5)2.1.整体程序流程图 (5)2.2.内存分配allocate()流程图 (6)2.3.内存回收callback()流程图 (7)五、算法的实现 (7)1.程序主要功能函数设计思想 (7)2.源程序清单 (8)3.测试用例与程序运行结果截图 (18)六、总结 (21)1.经验总结 (21)2.心得与体会 (21)七、参考文献 (22)1一、概述1、设计目的(1)了解多道程序系统中,多个进程并发执行的内存资源分配。
(2)模拟可变分区存储管理算法实现分区管理的最佳适应分配算法(3)利用最佳适应算法动态实现内存分配与回收(3)通过实现最佳算法来进一步了解动态分区模式的优缺点。
(4)掌握最佳适应分配算法,深刻了解各进程在内存中的具体分配策略。
2、开发环境PC机DOS;WINDOWS环境Visual C++6.0 for Windows二、需求分析克服固定分区中的主存资源的浪费,有利于多道程序设计,提高主存资源的利用率。
三、实验基本原理1、可变分区存储管理之最优适应算法分配的概念:分区存储管理是给内存中的进程划分适当大小的存储区,以连续存储各进程的程序和数据,使各进程能并发地执行。
最优适应分配算法扫描整个未分配区表或链表,从空闲区中挑选一个能满足用户进程要求的最小分区进行分配。
2、关于最优适应的一些基本原理:在可变分区模式下,在系统初启且用户作业尚未装入主存储器之前,整个用户区是一个大空闲分区,随着作业的装入和撤离,主存空间被分成许多分区,有的分区被占用,而有的分区时空闲的。
存储管理动态分区分配及回收算法
存储管理动态分区分配及回收算法存储管理是操作系统中非常重要的一部分,它负责对计算机系统的内存进行有效的分配和回收。
动态分区分配及回收算法是其中的一种方法,本文将详细介绍该算法的原理和实现。
动态分区分配及回收算法是一种将内存空间划分为若干个动态分区的算法。
当新的作业请求空间时,系统会根据作业的大小来分配一个合适大小的分区,使得作业可以存储在其中。
当作业执行完毕后,该分区又可以被回收,用于存储新的作业。
动态分区分配及回收算法包括以下几个步骤:1.初始分配:当系统启动时,将整个内存空间划分为一个初始分区,该分区可以容纳整个作业。
这个分区是一个连续的内存块,其大小与初始内存大小相同。
2.漏洞表管理:系统会维护一个漏洞表,用于记录所有的可用分区的大小和位置。
当一个分区被占用时,会从漏洞表中删除该分区,并将剩余的空间标记为可用。
3.分区分配:当一个作业请求空间时,系统会根据作业的大小,在漏洞表中查找一个合适大小的分区。
通常有以下几种分配策略:- 首次适应(First Fit): 从漏洞表中找到第一个满足作业大小的分区。
这种策略简单快速,但可能会导致内存碎片的产生。
- 最佳适应(Best Fit): 从漏洞表中找到最小的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
- 最差适应(Worst Fit): 从漏洞表中找到最大的满足作业大小的分区。
这种策略可以尽量减少内存碎片,但是分配速度相对较慢。
4.分区回收:当一个作业执行完毕后,系统会将该分区标记为可用,并更新漏洞表。
如果相邻的可用分区也是可合并的,系统会将它们合并成一个更大的分区。
总结来说,动态分区分配及回收算法是一种对计算机系统内存进行有效分配和回收的方法。
通过合理的分配策略和回收机制,可以充分利用内存资源,提高系统性能。
然而,如何处理内存碎片问题以及选择合适的分配策略是需要仔细考虑的问题。
操作系统-主存储器空间的分配和回收
实习四 主存储器空间的分配和回收一,实习题目本实习模拟在两种存储管理方式下的主存分配和回收。
第一题:在可变分区管理方式下采用最先适应算法实现主存分配和实现主存回收。
[提示]:可变分区方式是按作业需要的主存空间大小来分割分区的。
当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,假设有,则按需要量分割一个分区分配给该作业;假设无,则作业不能装入。
随着作业的装入、撤离,主存空间被分成许多个分区,有为了 说明哪些区是空闲的,可以用来装入新作业,必须要有一张空闲区说明表,格式如下:第一栏 第二栏其中,起址——指出一个空闲区的主存起始地址。
长度——指出从起始地址开始的一个连续空闲的长度。
状态——有两种状态,一种是“未分配”状态,指出对应的由起址指出的某个长度的区域是空闲区;另一种是“空表目”状态,表示表中对应的登记项目是空白〔无效〕,可用来登记新的空闲区〔例如,作业撤离后,它所占的区域就成了空闲区,应找一个“空表目”栏登记归还区的起址和长度且修改状态〕。
由于分区的个数不定,所以空闲区说明表中应有适量的状态为“空表目”的登记栏目,否则造成表格“溢出”无法登记。
上述的这张说明表的登记情况是按提示〔1〕中的例所装入的三个作业占用的主存区域后填写的。
(2) 当有一个新作业要求装入主存时,必须查空闲区说明表,从中找出一个足够大的空闲区。
有时找到的空闲区可能大于作业需要量,这时应把原来的空闲区变成两部分:一部分分给作业占用;另一部分又成为一个较小的空闲区。
为了尽量减少由于分割造成的空闲区,而尽量保存高地址部分有较大的连续空闲区域,以利于大型作业的装入。
为此,在空闲区说明表中,把每个空闲区按其地址顺序登记,即每个后继的空闲区其起始地址总是比前者大。
为了方便查找还可使表格“紧缩”,总是让“空表目”栏集中在表格的后部。
(3) 采用最先适应算法〔顺序分配算法〕分配主存空间。
按照作业的需要量,查空闲区说明表,顺序查看登记栏,找到第一个能满足要求的空闲区。
存储器的分配与回收算法实现
存储器的分配与回收算法实现一、引言存储器的分配与回收算法是计算机操作系统中的重要内容之一。
它涉及到内存管理、进程管理等多个方面,对计算机系统的性能和稳定性都有着重要的影响。
本文将从存储器分配与回收算法的基本原理、常见算法及其实现方式等方面进行详细介绍。
二、存储器分配与回收算法基本原理1. 存储器分配在计算机系统中,进程需要使用一定数量的内存空间来运行。
因此,操作系统需要为每个进程分配一定数量的内存空间。
存储器分配就是指操作系统为进程分配内存空间的过程。
2. 存储器回收当一个进程不再需要使用某段内存空间时,操作系统需要将该段内存空间释放出来,以便其他进程使用。
这个过程称为存储器回收。
三、常见的存储器分配与回收算法1. 首次适应算法(First Fit)首次适应算法是最简单、最常用的一种内存分配方法。
该方法从低地址开始查找可用块,并选择第一个满足要求(大小大于或等于所需大小)的块进行分配。
优点:实现简单,效率高。
缺点:容易产生内存碎片,导致内存利用率低。
2. 最佳适应算法(Best Fit)最佳适应算法是一种比首次适应算法更为优化的算法。
该算法从所有可用块中选择最小的一个块进行分配。
优点:可以有效减少内存碎片,提高内存利用率。
缺点:实现复杂度高,效率较低。
3. 最差适应算法(Worst Fit)最差适应算法是一种与最佳适应算法相反的方法。
该方法选择可用块中最大的一个块进行分配。
优点:容易实现,效率较高。
缺点:会产生大量的内存碎片,降低了内存利用率。
4. 快速适应算法(Quick Fit)快速适应算法是一种基于链表结构的动态分配方法。
该方法将可用块按照大小分类,并将它们组织成多个链表。
当需要分配内存时,只需在对应大小的链表中查找可用块即可。
优点:能够快速地找到合适大小的空闲块,提高了效率和内存利用率。
缺点:实现复杂度较高,需要维护多个链表结构。
四、常见的存储器分配与回收算法实现方式1. 静态分配静态分配是指在程序运行之前就确定好内存的使用情况,将内存空间划分为不同的区域,并为每个区域分配固定大小的内存空间。
主存储器空间的分配和回收
主存储器空间的分配和回收实验二主存储器空间的分配和回收一、实验题目模拟在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收。
[提示]:(1)、分页式存储器把主存分成大小相等的若干块,作业的信息也按块的大小分页,作业装入主存时可把作业的信息按页分散存放在主存的空闲块中,为了说明主存中哪些块已经被占用,哪些块是尚未分配的空闲块,可用一张位示图来指出。
位示图可由若干存储单元来构成,其中每一位与一个物理块对应,用0/1表示对应块为空闲/已占用。
(2)、假设某系统的主存被分成大小相等的64块,则位示图可用8个字节来构成,另用一单元记录当前空闲块数。
如果已有第0,1,4,5,6,9,11,13,24,31,共10个主存块被占用了,那么位示图情况如下:(3)、当要装入一个作业时,根据作业对主存的需要量,先查当前空闲块数是否能满足作业要求,若不能满足则输出分配不成功。
若能满足,则查位示图,找出为“0”的一些位,置上占用标志“1”,从“当前空闲块数”中减去本次占用块数。
按找到的计算出对应的块号,其计算公式为:块号= j 8+i其中,j表示找到的是第n个字节,I表示对应的是第n位。
根据分配给作业的块号,为作业建立一张页表,页表格式:(4) 、当一个作业执行结束,归还主存时,根据该作业的页表可以知道应归还的块号,由块号可计算出在位示图中的对应位置,把对应位的占用标志清成“0”,表示对应的块已成为空闲块。
归还的块数加入到当前空闲块数中。
由块号计算在位示图中的位置的公式如下:字节号 j=[块号/8] ([ ]表示取整)位数 i={块号/8} ({ }表示取余)(5) 设计实现主存分配和回收的程序。
假定位示图的初始状态如(2)所述,现有一信息量为5页的作业要装入,运行你所设计的分配程序,为作业分配主存且建立页表(格式如(3)所述)。
然后假定有另一作业执行结束,它占用的块号为第4,5,6和31块,运行你所设计的回收程序,收回作业归还的主存块。
存储器的分配与回收算法实现
存储器的分配与回收算法实现1. 引言在计算机系统中,存储器(Memory)是一种用于存储和检索数据的重要资源。
存储器的分配与回收算法实现是操作系统中的一项关键任务,它负责管理和组织存储器的分配与释放。
本文将深入探讨存储器的分配与回收算法实现的原理、常用算法及其优化方法。
2. 存储器的组织与分配2.1 存储器的组织存储器可以分为物理存储器和逻辑存储器。
物理存储器是计算机硬件中的实际存储器,如RAM(Random Access Memory)和ROM(Read-Only Memory);而逻辑存储器是在操作系统中抽象出来的概念,用于完成存储器的管理。
逻辑存储器可以通过分区、分页和段落等方式进行组织。
其中,分区是将物理存储器划分为若干个连续的大小相等或不等的区域,用于存放进程或数据;分页则将物理存储器划分为固定大小的页框,并将逻辑存储器划分为相同大小的页;段落则将物理存储器划分为不同大小的段,每个段可包含若干页。
2.2 存储器的分配方式存储器的分配方式通常包括固定分区分配和动态分区分配。
固定分区分配将物理存储器分为若干个固定大小的分区,每个分区可分配给一个进程或数据。
固定分区分配的特点是简单、高效,但会造成存储器的内部碎片。
动态分区分配则按需为进程或数据分配存储区域,可以更加灵活地利用存储器资源。
动态分区分配的主要算法包括首次适应算法、最佳适应算法和最坏适应算法等。
3. 存储器的回收算法存储器的回收算法是将不再使用的存储区域回收,并将其释放给其他进程使用的过程。
常用的存储器回收算法包括垃圾回收算法和页面置换算法。
3.1 垃圾回收算法垃圾回收算法是在动态内存分配中常用的一种回收算法,它通过自动检测和回收不再使用的存储空间,以避免内存泄漏和内存溢出等问题。
常见的垃圾回收算法包括引用计数法、标记-清除法和复制算法等。
•引用计数法:该算法通过记录每个对象被引用的次数来进行垃圾回收。
当一个对象被引用时,其引用计数加1;当一个对象不再被引用时,其引用计数减1。
页式存储管理方案中的内存分配
页式存储管理方案中的内存分配第一篇:页式存储管理方案中的内存分配页式存储管理方案中的内存分配用户提出内存空间申请,按一定策略检查内存空间,找出满足请求的空闲页面,分给申请者1首先接收输入文件:(1)内存空闲物理页面文件(文本文件),包括若干行,每行2项(起始物理页面号,连续的物理页面数)(2)进程占用物理内存数据文件(文本文件),包括若干行,若干项(进程号,物理页面号1,物理页面号2,……)建立空闲页面表,并在屏幕显示输出该表内容 20行该表中记录了内存中可供分配的空闲页面的起始页号和连续空闲的页面数3为每个进程建立一个页表,并在屏幕显示输出每个页表的内容页表记录了每个进程逻辑页面与物理页面的对应关系在用户界面根据用户提示接收一个内存申请,格式为:进程名,申请空间大小(单位为K字节)为该进程建立一个页表,显示输出该表内容,检查空闲页面表,为该进程分配相应的物理页面,并修改有关的数据结构(空闲页面表,页表)假设页面大小为4K重复4,5直到输入特殊字符(0)在屏幕显示输出最新的空闲页面表内容第二篇:可变分区存储管理方式的内存分配和回收#include//定义输入/输出函数#include//数据流输入/输出#include//字符串处理#include//参数化输入/输出const int MJ=10;//假定系统允许的最大作业数量为10typedef struct node{int address;int length;char tag[10];}job;job frees[MJ];int free_quantity;job occupys[MJ];int occupy_quantity;int read(){FILE *fp;char fn[10];cout<<“请输入初始空闲表文件名:”;cin>>fn;if((fp=fopen(fn,“r”))==NULL){ 其意义是在当前目录下打开文件file a,只允许进行“读”操作,并使fp指向该文件cout<<“错误,文件打不开,请检查文件名”<}else{while(!feof(fp)){fscanf(fp,“%d,%d”,&frees[free_q uantity].address,&frees[fr ee_quantity].length);free_quantity++;fscanf(文件指针,格式字符串,输入表列);}return 1;}return 0;}void sort(){int i,j,p;for(i=0;ip=i;for(j=i+1;jif(frees[j].addressp=j;}}if(p!=i){frees[free_quantity]=frees[i];frees[i]=frees[p];frees[p]=frees[free_quantity];}}}void view(){int i;cout<cout<<“输出空闲区表:n起始地址分区长度状态n”< for(i=0;icout.setf(2);cout.width(12);cout<cout.width(10);cout<cout.width(8);cout<}cout<cout<<“输出已分分区表:n起始地址分区长度占用作业名n”<for(i=0;icout.setf(2);cout.width(12);cout<cout.width(10);cout<cout.width(8);cout<}}void ear(){char job_name[10];int job_length;int i,j,flag,t;cout<<“请输入分配内存的作业名和空间大小:”;cin>>job_name;cin>>job_length;flag=0;for(i=0;iif(frees[i].length>=job_length){flag=1;}}if(flag==0){//未找到空闲区,返回cout<}else{t=0;i=0;while(t==0){if(frees[i].length>=job_length){//找到可用空闲区,开始分配t=1;}i++;}i--;occupys[occupy_quantity].address=frees[i].address;//修改已分配区表strcpy(occupys[occupy_quantity].tag,job_name);occupys[occupy_quantity].length=job_length;occupy_quantity++;if(frees[i].length>job_length){frees[i].address+=job_length;frees[i].length-=job_length;}else{for(j=i;jfrees[j]=frees[j+1];}free_quantity--;cout<<“内存空间成功:)”<}}}void reclaim()//回收作业所占的内存空间{char job_name[20];int i,j,flag,p=0;int address;int length;//寻找已分分区表中对应的登记项cout<<“输入要回收分区的作业名:”;cin>>job_name;flag=-1;for(i=0;iif(!strcmp(occupys[i].tag,job_name)){flag=i;address=occupys[i].address;length=occupys[i].length;}}if(flag==-1){ //在已分分区表中找不到作业cout<<“没有这个作业名”<}else{//修改空闲区表,加入空闲表for(i=0;iif((frees[i].address+frees[i].length)==address){ if(((i+1)for(j=i+1;jfrees[j]=frees[j+1];}free_quantity--;p=1;}else{frees[i].length+=length;p=1;}}if(frees[i].address==(address+length)){ frees[i].address=address;frees[i].length+=length;p=1;}}if(p==0){frees[free_quantity].address=address; frees[free_quantity].length=length;free_quantity++;}//删除分配表中的该作业for(i=flag;ioccupys[i]=occupys[i+1];}occupy_quantity--;}}void main(){int flag=0;int t=1;int chioce=0;int i;for(i=0;ifrees[i].address=-1;//空闲区表初始化frees[i].length=0;strcpy(frees[i].tag,“free”);occupys[i].address=-1;//已分分区表初始化occupys[i].length=0;strcpy(occupys[i].tag,“");}free_quantity=0;occupy_quantity=0;flag=read();while(flag==1){sort();cout<<”选择功能项:(0-退出,1-分配内存,2-回收内存,3-显示内存)n“<cin>>chioce;switch(chioce){case 0:flag=0;break;case 1:ear();break;case 2:reclaim();break;case 3:view();break;default:cout<<”没有该选项n"<}}}第三篇:编程中内存分配总结栈, 临时变量,大小有限制,函数返回后就被回收堆,可以动态分配,大小可近似认为无限制,可以一直存在堆:malloc(), free()需要自己申请与自己负责释放!适用于事先不知道需要分配多大空间的情况。
操作系统:页式管理的分配与回收算法(C语言)
操作系统:页式管理的分配与回收算法(C语言)#include<stdio.h> #include<stdlib.h>//#include<iomanip.h>//#include"windows.h"//#include"os.h"#define n 64//实验中假定主存的长度#define m 4//实验中假定每个作业分得主存块块数int p[m];//定义页struct{short int lnumber;//页号short int flag;//表示该页是否在主存,“1”表示在主存,“0”表示不在主存short int pnumber;//该页所在主存块的块号short int write;//该页是否被修改过,“1”表示修改过,“0”表示没有修改过short int dnumber;//该页存放在磁盘上的位置,即磁盘块号short int times;//被访问的次数,用于LRU算法}page[n];//定义页表//各个函数的实现如下:void computer(){int i;for(i=0;i<n;i++){page[i].lnumber = i;page[i].flag = 0;page[i].pnumber = 10000;//用10000表示为空page[i].write = 0;page[i].dnumber = i;page[i].times = 0;}//初始化页表for(i=0;i<m;i++){page[i].pnumber = i;}for(i=0;i<m;i++){p[i] = i;page[i].flag = 1;}//初始化页}void showpagelist(){int i;printf("页号\t是否在主存中\t块号\t是否被修改过\t磁盘块号\t访问次数\n");for(i=0;i<n;i++){printf("%d\t%d %d\t%d %d \t%d\n",page[i].lnumber,page[i].flag,page[i].pnumber,page [i].write,page[i].dnumber,page[i].times);}}void showpage(){int i;for(i=0;i<m;i++){printf("\t%d",p[i]);}printf("\n");}void transformation(){unsigned logicAddress,logicNumber,innerAddress,physicsAddress,physicsNumber;int i,head=0,fail = 0;int method,temppage=0;short int times = 10000;printf("请输入一个逻辑地址(四位十六进制数):");scanf("%x",&logicAddress);//读入逻辑地址logicNumber = logicAddress >> 10;//得到页号printf("页号为:%d\n",logicNumber);innerAddress = logicAddress & 0x03ff;//得到页内地址printf("页内地址为:%d\n",innerAddress);for(i=0;i<n;i++){if(logicNumber==(unsigned)page[i].lnumber){if(page[i].flag == 1){printf("请求的页面在主存中!\n");page[i].times++;physicsNumber = page[i].pnumber;//由页号得到块号printf("请求的主存块号为:%d\n",physicsNumber);physicsAddress = physicsNumber << 10 |innerAddress;//得到物理地址printf("请求的物理地址为:%d\n",physicsAddress);break;}else{printf("请求的页面不在主存中! 将进行缺页中断处理!\n请选择算法!\n"); printf("1.先进先出\n2.最近最少用!\n请选择置换算法\n");scanf("%d",&method);if(method == 1) //采用先进先出算法{printf("采用先进先出算法!\n");fail = p[head];printf("第:%d页将被替换\n",fail);p[head] = logicNumber;head = (head+1) % m;if(page[fail].write == 1)printf("第:%d页曾被修改过\n",fail);page[fail].flag = 0;page[logicNumber].flag = 1;page[logicNumber].write = 0;page[logicNumber].pnumber = page[fail].pnumber;page[fail].pnumber = 10000;page[logicNumber].times++;break;}else if(method == 2) //采用最近最少用算法{printf("采用最近最少用算法!\n");for(i=0;i<n;i++){if(page[i].flag == 1){if(page[i].times<times){times = page[i].times;temppage = page[i].lnumber;}}}printf("第:%d页将被替换\n",temppage);for(i=0;i<m;i++){if(p[i] == temppage){p[i] = logicNumber;}}if(page[temppage].write == 1)printf("第:%d页曾被修改过\n",temppage);page[temppage].flag = 0;page[logicNumber].flag = 1;page[logicNumber].write = 0;page[logicNumber].pnumber = page[temppage].pnumber; page[temppage].pnumber = 10000;page[logicNumber].times++;break;}else{printf("你输入有误,即将退出!");exit(1);}}}}}void main(){char c,d,temp;computer();showpage();showpagelist();T:transformation();printf("是否显示页和页表?(y/n)");scanf("%c",&temp);////忽略回车scanf("%c",&c);scanf("%c",&temp);////忽略回车switch(c){case 'y':showpage();showpagelist();case 'n':printf("是否继续进行请求分页?(y/n)"); scanf("%c",&d);if (d=='Y'||d=='y')goto T;else if (d=='N'||d=='n')exit(1);elseprintf("输入错误!\n");default:printf("输入错误!\n");}}。
内存管理、分配与回收模拟实验
华中师范大学计算机科学系实验报告书实验题目:内存管理、分配与回收课程名称:操作系统主讲教师:辅导教师:课程编号:班级:实验时间:一、实验目的:(1)掌握内存分区管理的基本思想,理解内存分配表。
(2)深入理解可变分区的内存分配策略,掌握首先适应算法、最佳适应算法和最坏适应算法。
(3)掌握内存碎片产生的途径以及解决碎片的方法——拼接技术。
(4)实现分区的回收。
针对内存管理的相关活动,研究内存空闲队列的动态组织与管理问题,以及在此基础上执行的内存分配与回收活动。
二、实验内容:本实验将利用伙伴系统来组织内存空闲块队列和已使用内存块队列。
从初始化快照、某一组作业申请内存块前的快照、分配成功后的快照等状态出发,结合内存分配原语(算法)和内存回收原语(算法)的实现,结合实际内存块的动态分配与回收情况(某一快照),研究内存空闲块队列的组织、变化及其队列管理方面的问题。
具体内容如下:(1)实现内存分配算法和内存回收算法。
(2)以伙伴系统的组织方式管理内存空闲队列和已使用内存块队列,具体的组织策略应分别考虑首次适应策略、最佳适应策略和最坏适应策略。
(3)考虑在某一内存使用一段时间的快照,给出一组作业的内存申请,判断该申请是否可以被满足。
三、实验要求(1)分配算法中切割空闲区是从低地址开始;(2)需考虑门限值情况,门限值是指切割空闲区后剩下的区域若小于一个用户给定的值时,就不切割该空闲区,统统分给申请者,这个值由用户指定;(3)回收算法需要考虑上邻、下邻、上下邻和不相邻四种情况。
四、实验环境:实践平台:windows编写环境:CodeBlocks编译器:g++五、实验设计原理(1)可变分区基本思想可变分区是指系统不预先划分固定分区,而是在装入程序时划分,使程序分配的大小正好等于程序的需求量,且分区的个数是可变的,这样有较大的灵活性,较之固定分区能获得更好的内存利用率。
其状态如图所示:(2)内存分配表内存分配表由两张表格组成:一张是已分配表,记录已装入的程序在内存中占用分区的起始地址和长度,并表之位指出占用分区的程序名;另一张是空闲区表,记录内存中可供分配的空闲区的起始地址和长度,用标志位指出该分区是未分配的空闲区。
实验三 分页管理的主存分配和回收
实验三分页管理的主存分配和回收班级:学号:姓名:1.实验内容主存的分配和去配2.实验目的(1)加深对分页管理概念的理解(2)深入了解分页管理如何进行分配和去配3.实验设计3.1 数据结构设计分页存储管理中,系统要建立一张主存物理块表来记录页框的状态,其中包含的信息有内存总量、已用空间、剩余空间、进程总数、已使用内存块数、当前内存是否有进程。
用0表示内存块空闲,1表示内存块在使用。
#define N 100 // 共有100个内存块int process[N][N+1]; // 存放每个进程的页表int block[N]; // 内存块状态标志数组,0:空闲,1:使用int blockCount; // 记录当前内存剩余空间int processCount; // 记录当前进程数进行主存分配时,先查看内存块的使用情况,看空闲块数是否满足用户进程的需要。
if(processCount>0){cout<<"内存详细使用情况如下:\n";for(int i=0;i<N;i++){if(process[i][0]>0){cout<<"进程号:"<<i<<"\n占用内存块:"<<process[i][0];for(int j=1,count=0;j<=process[i][0];j++){printf("%2d ",process[i][j],count++);if(count==15){putchar('\n');printf(" ");count = 0;}}putchar('\n');}}}elsecout<<"当前内存无进程!\n";空闲块数满足用户需求时,可以创建新的进程,注意进程号不能过大。
页式存储中的内存分配和管理
题目二:模拟页式存储管理中内存的分配和管理一.设计思想说明模拟页式存储管理,首先假定内存被分为2048块(块和页大小一致),利用位式图中该位的状态表示状况,判断它内存的块是否被占用,0表示内存块为空闲状态,新作业可申请该块;1表示内存被占用,新的作业不能占用该块。
该位示图使用32字长的字表示,故需要64个这样的字。
位示图存放在文件中,每行表示32字长的字,共64行。
块和页的大小为512字节。
程序中使用结构体node来存放作业的相关信息(加入内存的进程名,新作业的申请内存的大小(单位为字节),分配的块数,分配块在内存中的位置,最后块的碎片的大小(单位为字节));使用sum来记录当前的空闲的内存块数。
该程序在显示完内存的分配之后,使用switch—case来为用户提供可供是实现的功能。
用户选择不同的功能之后,程序会自动进入到不同的实现模块中,用户再依次根据程序的提示进行操作。
模拟页式存储中内存的分配和管理这个程序划分为了以下几个模块:显示当前的内存分配的位示图,添加新的作业,完成作业(将原来分配给用户的内存空间回收),显示作业的内存分配的页表等功能。
在添加新的作业的这个功能中,当用户申请的作业的存放空间大于当前内存拥有的最大的内存空间,则该程序不给予分配。
在完成作业的功能中,程序将原来分配给作业的内存空间按照存放在结构体中的内存空间的链表回收。
显示位示图的功能就是将现在的位示图显示到屏幕上。
显示作业的相关信息就是将存放该作业的节点中包括的所有内容显示出来。
二.相关数据结构的说明用来保存用户作业的相关信息的结构体的定义:typedef struct node{char jobname[20]; //申请内存空间的进程名int num; //申请空间的大小(字节数)int block; //分配的块数int nums[PAGES]; //保存分配的块号int slice; //保存碎片大小struct node *next;}jobs;用来存放用户作业链表的头节点的结构体指针:jobs *head;用来存放当前的内存中剩余的空间数:int sum;三.各个模块的算法流程1.从文件中读取位示图的模块:readdata()开始进入到inf.txt,string s,int iagetline(in,s)!=NULLGetline(in,s)!=NULL istringstream sin(s) b.push_back(ia) a.push_back(b)是结束否是否2.用户选择功能模块:choose()开始输入需要操作功能的代表添加作业模块完成作业模块显示作业信息模块显示位示图模块退出系统其他数字1 2 4 3 03. 添加作业模块:add()开始输入要添加的作业的进程名输入该作业需要的内存空间大小numnum%PAGESIZE==0是block=num/PAGESIZE否Block=num/PAGESIZE+1block<=sum是为这个作业申请一个节点,将作业的进程名,申请的字节数,占用的内存空的块数,这些块在内存中的位置,以及碎片的大小sum=sum-block将这个节点插在链表的最后一个位置上否进入到choose()模块中结束4.完成作业模块:finish()开始输入要回收的作业的进程名p=head,q=p->nextp->next!=NULLp=p->next否否strcmp(q->jobname,name)==0是回收为作业分配的内存空间,即将原来分配的空间的对应的位示图的标志由1改为0,将原来的链表链接好sum=sum+q->block删除这个节点结束5.显示位示图的模块:tableview()6.显示用户作业的相关信息的模块:pageview()开始p=head->nextp!=NULL输出该节点指向作业名,存放空间等相关信息是结束否开始i=0i<WORDNUMj<WORDj=0cout<<a[i][j] cout<<endl是结束否是否四.程序清单五.简单的使用说明1.作业的进程名作为唯一识别进程的主码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
题目: 模拟设计页式存储管理的分配与回收1需求分析页式管理把内存空间按页的大小划分成片或者页面(page frame),然后把页式统一管理。
图1 页的划分图2 基本页表示例静态分页管理的第一步是为要求内存的作业或进程分配足够的页面。
系统通过存储页面表、请求表以及页表来完成内存的分配工作。
页表指的是内存中的一块固定存储区。
页式管理时每个进程至少有一个页表。
请求表指的是用来确定作业或进程的虚拟空间的各页在内存中的实际对应位置;另外整个系统有一个存储页面表,其描述了物理内存空间的分配使用状况。
图3 请求表的示例存储页面表有两种构成方法:1、位示图法2、空闲页面链表法模拟设计页式存储管理的分配与回收要求能够满足如下的要求:(1)输入给定的内存页面数,页面大小,进程的个数及每个进程的页数。
(2)要求当某进程提出申请空间的大小后,显示能否满足申请,以及为该进程分配资源后内存空间的使用情况(被进程占用的页面,空闲的页面)。
2 功能设计2.1 算法分析首先,请求表给出进程或作业要求的页面数。
然后,由存储页面表检查是否有足够的空闲页面,如果没有,则本次无法分配。
如果有则首先分配设置页表,应的页好填入页表中。
图4 分配页面的算法流程2.2 数据结构页式管理把内存空间按页的大小划分成片或者页面,再按照一定的规律建立起页表,并通过请求表将分配内容显示出来.将页表和请求表的内容使用结构体来定义是比较方便的.//页表项结构typedef struct _pagetableitem{pageid pagenum; //页号blockid blocknum; //块号}pgtabitem; //页表typedef pgtabitem * pagetable;//请求表结构typedef struct _reqtable{unsigned pid; //进程号unsigned reqpagenum; //请求页面数pagetable pgtabadr; //页表始址bool state; //状态} reqtabitem;请求表还引入了支持快速插入和删除的list顺序容器来进行相关操作.list<reqtabitem> reqtable因为模拟设计的关系,页面的起始地址均应该为随机的数值,所以程序在设计过程中加入了随机数类的编写.class RandomNumber{private:unsigned long randseed;public:RandomNumber(unsigned long s=0);unsigned short Random(unsigned long n);double fRandom(void);};采用当前系统的时间值来生成伪随机数分配地址.定义随机数产生器:RandomNumber random定义内存页面数:int pagenum定义页面大小:int pagesize定义进程个数:int pnum用整数数组模拟分配的内存页面数int * mempage=new int[pagenum]2.3模块说明2.3.1 主函数主函数依次运行了程序中所实现的关键函数.int main(){InitSys(); //初始化系统MainChoice();//输出系统菜单Destroy(); //释放申请的动态内存return 0;}2.3.2 各个功能函数初始化内存页面:void Init_Mempage(void)获取内存使用情况:int Get_Mempagenum(void)初始化默认的请求表:void Init_Reqtable(void)为默认的进程分配内存:void Init_DistMem(void)手动创建进程,并分配内存:void Dist_Mem(void)释放申请的动态内存:void Destroy(void)结束指定进程:void Kill(void)2.3.3 打印函数打印出进程请求表:void PrintReqtable(void)打印出页表:void PrintPageTable(void)打印出内存使用情况:void PrintMem(void)打印出物理块的大小:void PrintBlockSize(void)2.3.4 其他函数初始化系统: void InitSys(void)输出主菜单:void MainMenu(void)选择运行分支:void MainChoice()3开发平台3.1开发平台(1)使用系统:Windows 7(2)使用语言:C++(3)开发工具:Visual C++ 20084测试用例,运行结果与运行情况分析4.1测试方法通过输入正常数据以及非正常数据对程序进行全方位测试4.2测试结果(1)程序主界面(2)输入进程号和页面数:(3)显示进程页表:(4)显示请求表(5)显示内存使用情况以及物理块大小(6)错误检验5源程序的主要部分#include <iostream>#include <cstdlib>#include <iomanip>#include <list>#include "page.h"#include "Random.h"using namespace std;list<reqtabitem> reqtable;RandomNumber random; //随机数产生器unsigned pagenum=random.Random(80)+21; //内存页面数21-100 unsigned pagesize=random.Random(16)+5; //页面大小5-20unsigned pnum=random.Random(4)+5;//进程的个数5-8int * mempage=new int[pagenum]; //用整数数组模拟内存页面数/*初始化内存页面*/void Init_Mempage(void){int i=0;for(i=0;i<int(pagenum);i++)mempage[i]=0; //数组全部赋初值}/*获取内存的使用情况*/int Get_Mempagenum(void){int sum=0;for(int i=0;i<int(pagenum);i++)if(mempage[i]==0)sum++;return sum; //判断有多少内存页面已经被使用}/*初始化默认的请求表*/void Init_Reqtable(void){int i;for(i=1;i<=int(pnum);i++){reqtabitem preq;preq.pid=i;preq.reqpagenum=random.Random(4)+2;//进程请求的页面大小-5preq.state=false;preq.pgtabadr=NULL;reqtable.push_back(preq); //依次压入容器}}/*为默认的进程分配内存*/void Init_DistMem(void){int reqpnum; //进程请求页面数int i;list<reqtabitem>::iterator pos=reqtable.begin();for(;pos!=reqtable.end();pos++){reqpnum=(*pos).reqpagenum;if(reqpnum>int(Get_Mempagenum())) //判断请求的内存页面数目是否大于剩余的{cout<<"没有足够的内存!"<<endl;cout<<endl;}else{(*pos).state=true;pagetable temp = new pgtabitem[reqpnum]; //新建临时页表项数组if(temp==NULL){cout<<"内存分配失败!"<<endl;exit(0);}(*pos).pgtabadr=temp;for(i=0;i<reqpnum;i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}}}/*手动创建进程,并分配内存*/void Dist_Mem(void){int i;reqtabitem preq; //新创建进程记录int pid; //进程号int reqpnum; //请求页面数bool flag=false;do{cout<<"请输入进程号:";flag=false;cin>>pid;for(list<reqtabitem>::iteratorpos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid){flag=true;cout<<"该进程号已经存在,请重新输入"<<endl;cout<<endl;break;}}}while(flag==true); //循环直到输入的Pid满足条件preq.pid=pid;cout<<"请输入需要的页面数:";cin>>reqpnum;preq.reqpagenum=reqpnum;preq.state=false;preq.pgtabadr=NULL;reqpnum=preq.reqpagenum;if(reqpnum>Get_Mempagenum()){cout<<"没有足够的内存,进程创建失败!"<<endl;cout<<endl;}else{preq.state=true;pagetable temp = new pgtabitem[reqpnum];if(temp==NULL){cout<<"内存分配失败!"<<endl;exit(0);}preq.pgtabadr=temp;for(i=0;i<int(reqpnum);i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}reqtable.push_back(preq); //将该进程的记录加入请求表}/*程序结束时,释放申请的动态内存*/void Destroy(void){list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).state==true)delete [](*pos).pgtabadr;}reqtable.clear();}/* 打印出进程请求表*/void PrintReqtable(void){cout<<endl;cout<<"|--------------------------------------------------------------------|"<<endl;cout<<"| 进程请求表|"<<endl;cout<<"|--------------------------------------------------------------------|"<<endl;cout<<"|"<<setw(8)<<"进程号"<<setw(16)<<"请求页面数"<<setw(16)<<"页表起始地址"<<setw(16)<<"页表长度"<<setw(16)<<"状态|"<<endl;cout<<"|---------------------------------------------------------------------|"<<endl;list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){cout<<"|"<<setw(8)<<(*pos).pid<<setw(16)<<(*pos).reqpagenum<<setw(16)<<(*pos).pgtabadr<<setw(16)<<((*pos).reqpagenum) * pagesize;if((*pos).state)cout<<setw(4)<<"已分配|"<<endl;elsecout<<setw(4)<<"未分配|"<<endl;if((*pos).pid!=reqtable.back().pid)cout<<"|--------------------------------------------------------------------|"<<endl;elsecout<<"|--------------------------------------------------------------------|"<<endl;}}/*打印页表*/void PrintPageTable(void){unsigned pid;int i;bool flag=false;cout<<"请输入进程号:";cin>>pid;list<reqtabitem>::iterator pos=reqtable.begin();for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid&&(*pos).state==true){flag=true;cout<<"|---------------------------|"<<endl;cout<<"| 此进程的页表|"<<endl;cout<<"|---------------------------|"<<endl;cout<<"|"<<setw(16)<<"页号"<<setw(6)<<"块号|"<<endl;cout<<"|---------------------------|"<<endl;int reqpagenum=(*pos).reqpagenum;for(i=0;i<reqpagenum;i++){cout<<"|"<<setw(16)<<(*pos).pgtabadr[i].pagenum<<setw(6)<<(*pos).pgtabadr[i].blocknum<<" |"<<endl;if(i!=reqpagenum-1)cout<<"|---------------------------|"<<endl;elsecout<<"|---------------------------|"<<endl;}}}if(flag==false)cout<<"系统中不存在该进程或者该进程还没有被分配内存!\n";cout<<endl;}void PrintMem(void){cout<<"内存总块数为"<<pagenum<<",已经使用了"<<pagenum-Get_Mempagenum()<<"块!"<<endl;cout<<"现在还有"<<Get_Mempagenum()<<"块内存区域空闲!"<<endl;cout<<endl;}void PrintBlockSize(void){cout<<"物理块大小为:"<<pagesize<<"KB"<<endl;cout<<endl;}/*结束指定进程*/void Kill(void){bool flag;int i;reqtabitem temp;list<reqtabitem>::iterator pos=reqtable.begin();int pid;do{cout<<"请输入进程号:";flag=false;cin>>pid;for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).pid==pid){flag=true;temp=*pos;break;}}if(flag==false)cout<<"系统中不存在该进程!"<<endl;cout<<endl;}while(flag==false);for(i=0;i<int(temp.reqpagenum);i++)mempage[temp.pgtabadr[i].blocknum]=0;reqtable.remove(temp);//重新为没有分配到内存的进程分配内存for(pos=reqtable.begin();pos!=reqtable.end();pos++){if((*pos).state==false){int reqpnum;reqpnum=(*pos).reqpagenum;if(reqpnum<=Get_Mempagenum()){(*pos).state=true;pagetable temp = new pgtabitem[reqpnum];if(temp==NULL){cout<<"内存分配失败!"<<endl;cout<<endl;exit(0);}(*pos).pgtabadr=temp;for(i=0;i<int(reqpnum);i++){temp[i].pagenum=i; //页表的页号int randnum=random.Random(pagenum)+1;//随机产生一个块号while(mempage[randnum]==1)randnum=random.Random(pagenum)+1;temp[i].blocknum=randnum;//页表的块号mempage[randnum]=1;}}}}}/*初始化系统*/void InitSys(void){cout.setf(ios::left);//左对齐Init_Mempage();Init_Reqtable();Init_DistMem();}/*输出主菜单*/void MainMenu(void){cout<<"页式存储管理的分配与回收"<<endl;cout<<"1.手动创建进程"<<endl;cout<<"2.显示进程页表"<<endl;cout<<"3.显示请求表"<<endl;cout<<"4.撤销进程"<<endl;cout<<"5.显示内存使用情况"<<endl;cout<<"6.显示物理块大小"<<endl;cout<<"7.退出系统"<<endl;cout<<"请输入您的选择(0--7):";}/*选择函数*/void MainChoice(){int choice;do{MainMenu();cin>>choice;switch(choice){case 1:Dist_Mem();break;case 2:PrintPageTable();break;case 3:PrintReqtable();break;case 4:Kill();break;case 5:PrintMem();break;case 6:PrintBlockSize();break;case 7:break;default :cout<<"输入有误,请重新输入.\n";cout<<endl;break;}}while(choice!=7);}int main(){InitSys();//初始化系统MainChoice();//输出系统菜单Destroy();//释放申请的动态内存return 0;}6自我评价与总结此次试验是完全在自己独立完成的,首先在分析问题并把问题转化为编程问题,我觉得个人把握的很好,对页式管理的基本原理理解的比较透彻;其次我用了个随机函数来模拟页表起始地址和物理块大小等变量,使得输出的结果显得随机性较强,符合系统真实分配的情况. 另外对于进程请求表使用顺序容器操作,结构体保存项目的设计也独具匠心,配合迭代器的使用达到类似栈的用途,输出请求表的时候比较清晰明了.但是程序还有不足之处,程序仅仅只能从直观数值上来体现页式管理的随机分配的特性,并没有办法像linux之类操作系统一般真正的进行内存分配与回收,这是课后深入研究的一个方面。