操作系统-基本分页存储管理(内有代码)
- 格式:doc
- 大小:163.00 KB
- 文档页数:9
注意:1)“本章要点”部分,用红字标注的不是期末考试出题范围。
2)“习题部分”用蓝字标注的是重点习题,期末考试50%的题目是这些习题的原题。
红字标注的习题期末考试不考,仅供考研的同学参考。
3)大部分习题答案只给出要点,同学们可以自行适当补充,但一定要简明扼要。
4)如“本章要点”部分用红字标注的非考试内容,在“习题”部分有相关的重点习题,则对该部分内容只需做该习题即可。
------------------------------------------------------------第四章存储器管理要点4.1 存储器的层次结构理解P116图4-1的存储器层次结构,知道这种结构从经济上考虑,具有好的性能/价格比。
了解P117-118高速缓存CACHE和磁盘缓存,知道它们使用的淘汰算法与虚拟内存的页面置换算法是基本相同的。
4.2 程序的装入和链接这一小节的内容是一些重要的专业常识。
应了解本小节介绍的各种装入和链接方法,要求结合Windows操作系统及C 语言的实际去理解上述装入和链接方法(联系实际部分可上网查询)。
4.3 连续分配方式通用操作系统大都不用连续分配方式,有些嵌入式OS可能使用这种分配方式。
这一小节只需阅读P121-124即可。
4.4 基本分页存储管理方式这是本章最重要的一小节,要求全读。
重点理解页面、物理块、页表、页表的访存、物理地址、逻辑地址、快表(TLB)等概念及相互关系。
4.5 基本分段存储管理方式阅读4.5.1,知道为什么要分段。
阅读4.5.2 知道分段的原理。
考研的同学要知道段表、地址变换,知道分段和分页的主要区别。
阅读4.5.3 知道分段有利于信息共享,知道“纯代码”的概念。
阅读4.5.4 知道什么是段页式存储。
需要补充说明的是:教材说过,分段方便编程,主要是指方便汇编语言程序员,和设计高级语言编译器的程序员。
对使用高级语言进行应用编程的程序员来说,段是透明的,一般不能用高级语言代码去操作段。
第四章存储器管理第0节存储管理概述一、存储器的层次结构1、在现代计算机系统中,存储器是信息处理的来源与归宿,占据重要位置。
但是,在现有技术条件下,任何一种存储装置,都无法从速度、容量、是否需要电源维持等多方面,同时满足用户的需求。
实际上它们组成了一个速度由快到慢,容量由小到大的存储装置层次。
2、各种存储器•寄存器、高速缓存Cache:少量的、非常快速、昂贵、需要电源维持、CPU可直接访问;•内存RAM:若干(千)兆字节、中等速度、中等价格、需要电源维持、CPU可直接访问;•磁盘高速缓存:存在于主存中;•磁盘:数千兆或数万兆字节、低速、价廉、不需要电源维持、CPU 不可直接访问;由操作系统协调这些存储器的使用。
二、存储管理的目的1、尽可能地方便用户;提高主存储器的使用效率,使主存储器在成本、速度和规模之间获得较好的权衡。
(注意cpu和主存储器,这两类资源管理的区别)2、存储管理的主要功能:•地址重定位•主存空间的分配与回收•主存空间的保护和共享•主存空间的扩充三、逻辑地址与物理地址1、逻辑地址(相对地址,虚地址):用户源程序经过编译/汇编、链接后,程序内每条指令、每个数据等信息,都会生成自己的地址。
●一个用户程序的所有逻辑地址组成这个程序的逻辑地址空间(也称地址空间)。
这个空间是以0为基址、线性或多维编址的。
2、物理地址(绝对地址,实地址):是一个实际内存单元(字节)的地址。
●计算机内所有内存单元的物理地址组成系统的物理地址空间,它是从0开始的、是一维的;●将用户程序被装进内存,一个程序所占有的所有内存单元的物理地址组成该程序的物理地址空间(也称存储空间)。
四、地址映射(变换、重定位)当程序被装进内存时,通常每个信息的逻辑地址和它的物理地址是不一致的,需要把逻辑地址转换为对应的物理地址----地址映射;地址映射分静态和动态两种方式。
1、静态地址重定位是程序装入时集中一次进行的地址变换计算。
物理地址= 重定位的首地址+ 逻辑地址•优点:简单,不需要硬件支持;•缺点:一个作业必须占据连续的存储空间;装入内存的作业一般不再移动;不能实现虚拟存储。
操作系统——页式存储管理分区式存储管理最⼤的缺点是碎⽚问题严重,内存利⽤率低。
究其原因,主要在于连续分配的限制,即它要求每个作⽤在内存中必须占⼀个连续的分区。
如果允许将⼀个进程分散地装⼊到许多不相邻的分区中,便可充分地利⽤内存,⽽⽆需再进⾏“紧凑”。
基于这⼀思想,产⽣了“⾮连续分配⽅式”,或者称为“离散分配⽅式”。
连续分配:为⽤户进程分配的必须是⼀个连续的内存空间。
⾮连续分配:为⽤户进程分配的可以是⼀些分散的内存空间。
分页存储管理的思想:把内存分为⼀个个相等的⼩分区,再按照分区⼤⼩把进程拆分成⼀个个⼩部分。
分页存储管理分为:实分页存储管理和虚分页存储管理⼀、实分页式存储管理实分页式存储最⼤的优点是内存利⽤率⾼,与⽬前流⾏的虚分页存储管理相⽐,具有实现简单,程序运⾏快的优点。
⽬前,飞速发展的硬件制造技术使得物理内存越来越⼤,因此我们认为,实分页式存储管理将是⼀种最有发展前途的存储管理⽅式。
1.1、基本原理假设⼀个⼤型饭店,所有的客房都是标准的双⼈间,部分客房已经住进客⼈,现在⼜有⼀个旅游团要求⼊住。
接待员统计了⼀下,对旅游团领队说:“贵团全体成员都能住下,两⼈⼀个房间,但是不能住在同⼀楼层了,因为每层空着的客房不够,更没有⼏个挨着的。
请原谅!”。
对于这样的安排,⼀般⼈不会感到奇怪。
因为旅游团本来就是由⼀位位个⼈或夫妻等组成的,⽽饭店的客房本来也是两⼈⼀间的,两⼈⼀组正好可住在⼀个客房⾥;另外,饭店⼏乎每天都有⼊住的和退房的客⼈,想在同⼀楼层找⼏间挨着的客房实在不容易。
①将整个系统的内存空间划分成⼀系列⼤⼩相等的块,每⼀块称为⼀个物理块、物理页或实页,页架或页帧(frame),可简称为块(block)。
所有的块按物理地址递增顺序连续编号为0、1、2、……。
这⾥的块相当于饭店的客房,系统对内存分块相当于饭店把⼤楼所有的客房都设计成标准的双⼈间。
②每个作业的地址空间也划分成⼀系列与内存块⼀样⼤⼩的块,每⼀块称为⼀个逻辑页或虚页,也有⼈叫页⾯,可简称为页(page)。
操作系统实验-存储管理操作系统实验-存储管理1、引言1.1 概述在操作系统中,存储管理是一个关键的任务。
它负责将程序和数据加载到内存中,管理内存的分配和回收,并确保不同进程之间的内存互不干扰。
本实验旨在深入了解并实践存储管理的相关概念和算法。
1.2 目的本实验的目的是让学生通过实际操作,了解存储管理的基本原理和常用算法,包括分页、分段和虚拟内存等。
通过实验,学生将学会如何实现内存分配和回收,以及处理内存碎片等问题。
1.3 实验环境- 操作系统:Windows、Linux、MacOS等- 编程语言:C、C++等2、实验步骤2.1 实验准备- 安装相应的开发环境和工具- 创建一个空白的项目文件夹,用于存放实验代码和相关文件2.2 实验一、分页存储管理- 理解分页存储管理的概念和原理- 实现一个简单的分页存储管理系统- 设计测试用例,验证分页存储管理的正确性和有效性2.3 实验二、分段存储管理- 理解分段存储管理的概念和原理- 实现一个简单的分段存储管理系统- 设计测试用例,验证分段存储管理的正确性和有效性2.4 实验三、虚拟存储管理- 理解虚拟存储管理的概念和原理- 实现一个简单的虚拟存储管理系统- 设计测试用例,验证虚拟存储管理的正确性和有效性3、实验结果分析3.1 分页存储管理结果分析- 分析分页存储管理系统的性能优缺点- 比较不同页面大小对系统性能的影响3.2 分段存储管理结果分析- 分析分段存储管理系统的性能优缺点- 比较不同段大小对系统性能的影响3.3 虚拟存储管理结果分析- 分析虚拟存储管理系统的性能优缺点- 比较不同页面置换算法对系统性能的影响4、总结与展望4.1 实验总结- 总结本次实验的收获和体会- 分析实验中遇到的问题和解决方法4.2 实验展望- 探讨存储管理领域的未来发展方向- 提出对本实验的改进意见和建议附件:无法律名词及注释:- 存储管理:操作系统中负责管理内存的任务,包括内存分配、回收和管理等功能。
考研操作系统-存储管理(二)(总分:108.00,做题时间:90分钟)一、单项选择题(总题数:34,分数:68.00)1.对主存储器的访问,是( )。
A.以页(块)或段为单位B.以字节或字为单位C.随存储器的管理方案不同而异D.以用户的逻辑记录为单位A.B. √C.D.本题考查对主存的访问,不是对主存的分配。
主存的编址以字节为单位,对主存的访问也是以字节为单位。
因此本题选择B。
2.在虚拟内存管理中,地址变换机构将逻辑地址变换为物理地址,形成该逻辑地址的阶段是( )。
A.编辑 B.编译 C.链接 D.装载A.B. √C.D.编译过程指编译程序将用护源代码编译成目标模块。
源地址编译成目标程序时,会形成逻辑地址。
因此本题选择B。
3.把作业空间中使用的逻辑地址变换为内存中的物理地址的过程称为( )。
A.加载 B.重定位 C.物理化 D.逻辑化A.B. √C.D.本题考查重定位的概念。
由于作业装入内存时分配的内存空间与作业的地址空间是不一致的。
因此在作业装入或执行时,不对有关逻辑地址部分进行相应的修改,会导致错误的结果。
这种将作业的逻辑地址变换为物理地址的过程称为“地址重定位”。
因此本题选择B。
4.为了保证一个程序中主存中改变了存放位置之后仍能正常执行,则对主存空间应采用( )技术。
A.静态重定位 B.动态重定位 C.动态分配 D.静态分配A.B. √C.D.本题考查重定位的相关概念,而不是内存分配方式,所以首先排除C和D选项。
静态重定位中,地址变换通常是在装入时一次性完成,之后地址都不再改变,称为静态重定位。
动态重定位采用动态运行时装入方式,可以保证一个程序在主存中改变了存放位置后仍然能正确执行。
因此本题选择B。
5.在存储管理中采用交换与覆盖技术,其目的是( )。
A.从物理上扩充内存 B.实现主存共享C.节省存储空间 D.提高内存利用率A.B.C.D. √本题考查交换与覆盖技术的基本概念。
采用交换与覆盖技术不会扩充物理内存,可以提高内存利用率。
操作系统第五章复习题一、选择题1、虚拟存储器功能的管理方法包括()。
A 可变分区存储管理B 基本分页存储管理C 请求分段存储管理D 段页式存储管理2、虚拟存储器的最大容量()。
A 由作业的地址空间决定B 是任意的C 由计算机的地址结构决定的D 为内、外容量之和3、下面的页面置换算法中会产生所谓Belady 异常现象的是()。
A 最佳页面置换算法(OPT)B 先进先出页面置换算法(FIFO)C 最近最久未使用页面置换算法(LRU)D 最少使用页面置换算法(LFU)4、实现虚拟存储器的目的是()。
A 实现存储保护B 实现程序浮动C 扩充辅存容量D 扩充内存容量5、把作业地址空间使用的逻辑地址变成内存物理地址为()。
A 加载B 重定位C 物理化D 逻辑化6、虚拟存储管理系统的基础是程序的()理论。
A 局部性B 全局性C 动态性D 虚拟性7、从下列关于非虚拟存储器的论叙中,选出一条正确的论叙。
()A 要求作业在运行前,必须全部装入内存,且在运行过程中也必须一直驻留内存。
B 要求作业在运行前,不必全部装入内存,且在运行过程中不必一直驻留内存。
C 要求作业在运行前,不必全部装入内存,但在运行过程中必须一直驻留内存。
D 要求作业在运行前,必须全部装入内存,且在运行过程中不必一直驻留内存。
二、判断题1、虚拟存储器时物理上扩充内存容量。
(F )2、为提高请求分页系统中内存的利用率,允许用户使用不同大小的页面。
(F )3、在请求分页式系统中,以页为单位管理用户的虚空间,以段为单位管理内存空间。
(F )三、填空题1、在页式存储器管理系统中,常用的页面淘汰算法有:(最佳),选择淘汰不再使用或最远的将来才使用的页;( FIFO),选择淘汰在内存驻留时间最长的页;2、在请求分页系统中,若逻辑地址中的页号超过页表控制寄存器中的页表长度,则会引起(越界中断);否则,若所需的页不在内存中,则会引起(缺页中断)。
四、简答题1、虚拟存储器有哪些特征?其中最本质的特征是什么?2、实现虚拟存储器需要哪些硬件支持?3、说明请求分段系统中的缺页中断处理过程。
基本分页存储管理实验目的连续内存分配方式会形成许多“碎片”,虽然可以通过“紧凑”方法将许多碎片拼接成可用的大块空间,但须为之付出很大开销。
如果允许将一个进程直接分散地装入到许多不相邻接的分区中,则无需再进行“紧凑”。
基于这一思想而产生了离散分配方式。
如果离散分配的基本单位是页,则称为分页存储管理方式;如果离散分配的基本单位是段,则称为分段存储管理方式。
在分页存储管理方式中,如果不具备页面兑换功能,则称为基本的分页存储管理方式,或称为纯分页存储管理方式,它不具备支持虚拟存储器的功能,它要求把每个作业全部装入内存后方能运行。
本实验通过程序模拟操作系统的基本分页存储管理方式,进一步理解这一内存分配方式的原理和特点,加深对理论知识的掌握。
实验要求1、用C语言或Java语言编写程序模拟操作系统对内存的基本分页存储管理方式2、程序要能正确对“内存”进行“分配”和“回收”,能接受用户的输入,显示内存的分配情况,并有一定的容错能力。
3、每个人独立按时完成实验内容。
实验内容本实验假定内存空间已经按块划分,目标程序无需关心内存块大小等底层细节,只需按算法对内存块进行分配即可。
程序应该实现以下功能:1、内存初始化。
假定内存块共有N个,初始化后的内存空间应该有一部分已经被使用,这可以用随机数或程序内部的其他算法完成。
2、程序应该能接受用户输入的进程信息,并为之分配内存,返回分配结果(成功或失败),注意,此处应该考虑到不合法的输入并进行相应处理。
3、程序能回收用户指定的进程所占用的内存空间,因此,程序可能需要为每个进程分配一个唯一的进程号并给出详细的提示信息。
4、能直观合理地显示内存分配情况。
5、程序界面友好,便于操作和查看运行结果。
#include <stdio.h>#include <windows.h>#define N 100 // 共有100个内存块int process[N][N+1]; // 存放每个进程的页表int block[N]; // 内存块状态标志数组,0:空闲,1:使用int blockCount; // 记录当前内存剩余空间int processCount; // 记录当前进程数bool flag = true;void init();void output();bool createProcess();bool endProcess();void init(){int i, j;// 初始化内存状态标志数组for (i=0; i<N; i++)block[i] = 0;for (i=0; i<20; i++)block[rand()%(N-1)] = 1;blockCount = 0;for (i=0; i<N; i++)if (block[i] == 0)blockCount++;// 初始化存放进程的数组for (i=0; i<N; i++){process[i][0] = 0;for (j=1; j<N; j++)process[i][j] = -1;}processCount = 0;printf("初始化结果如下:");output();flag = false;}void output(){printf("\n内存总量:%d 块, 已用空间:%d 块, 剩余空间:%d 块, 进程总数:%d 个\n", N, N-blockCount, blockCount, processCount);if (flag && blockCount < N){printf("已使用的内存块(%d):\n", N-blockCount);for (int k=0,count=0; k<N; k++){if (block[k] == 1)printf("%2d ", k, ++count);if (count == 15){putchar('\n');count = 0;}}putchar('\n');}// 输出各进程占用内存详细情况if (processCount > 0){printf("内存详细使用情况如下:\n");for (int i=0; i<N; i++){if (process[i][0] > 0){printf("进程号:%d \n占用内存块(%2d):", i, 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');}}}elseprintf("当前内存无进程!\n");/*// 输出空闲内存块if (blockCount > 0){printf("空闲内存块(%d):\n", blockCount);for (int k=0,count=0; k<N; k++){if (block[k] == 0)printf("%2d ", k, ++count);if (count == 15){putchar('\n');count = 0;}}putchar('\n');}*/putchar('\n');}bool createProcess(){int pid, pages, k = 0;loop:printf("请输入进程号(小于%d)和所需页面数:", N);scanf("%d%d", &pid, &pages);if (pid > 99){printf("错误!进程号过大!\n");goto loop;}if (pages > blockCount)return false;blockCount -= pages;process[pid][0] = pages;for (int i=1; i<=pages; i++){while (block[k]==1 && k<100)k++;process[pid][i] = k;block[k] = 1;k++;}processCount++;return true;}bool endProcess(){int pid, pages;if (processCount < 1){printf("当前内存没有进程!\n\n");return false;}printf("当前内存中的进程有%d 个,进程号为:", processCount);for (int i=0; i<N; i++)if (process[i][0] > 0)printf("%2d ", i);putchar('\n');printf("请输入您要结束的进程号(小于%d):", N);scanf("%d", &pid);pages = process[pid][0];if (pages == 0){printf("对不起!该进程不存在!\n");return false;}for (int j=1; j<pages; j++){block[process[pid][j]] = 0;process[pid][j] = -1;}process[pid][0] = 0;processCount--;blockCount += pages;return true;}void menu(){int choice;while (true){printf("操作菜单:\n");printf(" 1 --> 创建进程\n 2 --> 结束进程\n 3 --> 查看内存\n 0 --> 退出程序\n");printf("请输入您要进行的操作:");scanf("%d", &choice);switch (choice){case 1:if (createProcess())printf("创建新进程成功!\n\n");elseprintf("抱歉!内存空间不足,创建新进程失败!\n\n");break;case 2:if (endProcess())printf("进程已结束!\n\n");elseprintf("进程结束失败!\n\n");break;case 3:output();break;case 0:return ;default:printf("对不起!您的选择有误!请重新选择!\n\n");}}}void main(){init();menu();}实验总结基本分页的思想是比较简单的,而且实验前老师已经给出了一种可行的数据结构来存储程序中需要用到的数据,因此这个实验在构思上是没有多少难度的。
由于程序中主要使用的是数组,操作起来比较方便,不像前两个实验需要用到大量的链表操作。
在这次试验中,我主要遇到了以下一些问题:1、程序刚写完时,记录“内存”中的进程数的变量和当前剩余总内存的变量的值不正确,经检查后发现是在结束进程时没有同时更新这些数据。
2、内存使用情况应该以哪种形式输出以及输出哪些信息。
最终我选择了尽可能详细地输出有用信息,通过空格、空行、对齐等手段尽力使输出格式简洁美观。
比如,在输出每个进程的内存使用情况时,首先输出该进程占用的总内存,然后以统一的对齐方式依次输出各个内存块编号。
当然,对于不同的模块输出的信息也应该不一样,比如,内存初始化结束后应该输出哪个内存块被占用了,否则无法判断后续的内存分配是否正确,但在以后查看内存使用情况时则不必把所有已占用的内存块输出,因为每个进程都会单独把自己占用的内存块显示出来。