内功修炼之操作系统学习(存储管理)
作者:网络转载 发布时间:[ 2012/7/6 13:26:27 ] 推荐标签:
存储器管理负责管理计算机系统中重要的资源---主存储器。任何程序和数据必须载入到主存中才得以执行和处理,因此存储器管理的优劣直接影响系统的性能。
主存分为两部分:一部分是系统区,用于存放操作系统内核程序和数据结构等。另一部分是用户区,用于存放应用程序和数据。
计算机系统采用层次结构的存储系统。以便在容量大小、速度快慢、价格高低等诸多因素中取得平衡。它分为五个层次:寄存器,高速缓存,主存储器,磁盘,磁带等五层。寄存器,高速缓存和主存储器属于操作系统存储管理管辖范畴。磁盘和磁带属于设备管理的管辖对象。
由于程序在执行和处理数据时往往存在顺序性和局部性,因此在执行时并不需要将其全部调入主存,而仅调用当前使用的一部分,其他部分待需要时再逐步调入。基于这个原理操作系统可以向用户提供比实际主存大得多的存储空间,可以设计出多级层次式体系结构的存储子系统。
源程序经过编译,链接,装入三个阶段后才能装入主存执行。一个程序可由独立编写且具有不同功能的多个源程序模块组成。由于模块包含外部引用:指向其他模块中的数据或函数的地址或包含对库函数的引用。编译程序负责记录引用的发生位置,编译或汇编的结果将产生相应的多个目标模块,每个模块都附有供引用使用的内部符号表和外部符号表。符号表中依次给出个符号名及在本目标模块中的名字地址,在模块被链接时进行转换。
链接程序的作用是把多个目标模块链接成一个完整的可重定位程序,这需要解析内部和外部符号表,把对符号的引用转换为数值引用,将对符号引用的程序入口点和数据引用点转换为数值地址。Linker首先将主程序调入工作区,然后扫描外部符号表,获得外部符号。用取得的符号名从标准函数库或其他库中找出此符号对应的.o文件,装入工作区并拼接到主程序之后作为程序的一部分。
磁盘中存储的代码模块使用的是逻辑地址。逻辑地址空间可以是一维的,从0开始线形排列。也可以是二维的,此时整个程序被分为多个段,每段都有不同的段号,段内地址从0开始编址。
进程运行时,数据和代码模块被装入物理地址空间,程序和数据的实际地址通常不可能同原来的逻辑地址一致。把逻辑地址转换为物理地址的过程称为地址重定位(与基址重定位相区别)。有两种方式:
1:静态地址重定位:由载入程序实现地址转换,将所有的逻辑地址修改成主存物理地址。地址转换工作在进程执行前一次完成,无须硬件支持,易于实现,但是不允许程序在进程中移动位置。早期的计算机系统使用此方法。
2:动态地址重定位:加载程序将程序的数据和代码加载到指定的主存区域后,并不对链接器处理过的应用程序的逻辑地址进行修改,但程序在主存的起始地址被置入硬件专用寄存器---重定位寄存器。程序执行过程中,每当cpu访问数据和代码时,由硬件截取此逻辑地址,并在它被发送到主存储器之前加上重定位寄存器的值以便实现地址转换。这被称为动态重定位,地址转换被推迟到后的可能时刻--执行时才完成。这允许程序在主存中移动,便于程序共享且主存利用率高。
为了支持动态重定位cpu至少要有三个重定位寄存器。将代码段、数据段和堆栈段分别作为三个可重定位的模块。Intel x86有6个重定位寄存器。
要将动态地址重定位与根据重定位段进行的基址重定位区分开来。基址重定位是当exe或dll没有加载到其基址时,所有涉及对逻辑地址引用的代码都需要修改成相对于exe或dll实际载入的逻辑地址条件下的偏移地址。它是对逻辑地址进行操作。而当exe或dll被加载到基地址时,基址重定位不会发生。但是任何程序都会进行动态地址重定位,将逻辑地址转换为物理地址。
在多道程序设计中,可用的主存通常被多个进程共享,必须允许进程所使用的内存因对换或空闲区收集而被移动,这需要动态地址重定位支持。无论采取何种重定位方式,通常进程运行时会对需要访问所有主存地址进行检查,确保进程仅访问自己的存储区。这是地址越界保护,它依赖于硬件。除了地址越界保护之外,还要进行访问权限检查,如允许读、写、执行等,从而保证数据的安全性和完整性,这是信息存取保护。
固定分区存储管理的基本思想:主存空间被划分成数目固定不变的分区,各个分区大小不等,每个分区只装入一个作业,若多个分区都装有作业则它们可以并发执行。缺点:预先规定分区大小使得大作业无法装入。作业很少会恰好填满分区,主存利用率不高。
可变分区管理又称为动态分区管理,按照作业大小来划分分区,但划分的时间、大小、位置都是动态的。系统把作业装入主存时,根据其所需要的主存容量查看是否有足够的空间。若有,则按需分配一个分区给此作业;若无,则令此作业等待主存资源 。由于分区大小是按需求而定的,因此分区数目是可变的。这可以提高主存利用率。
用于管理的数据结构由两张表组成:已分配分区表和未分配区表。当装入新作业时,从未分配表中找出一个足够容纳它的空闲区。将此区分成两部分,一部分用来装入作业,另一部分仍是空闲区。然后在已分配的表中登记新作业的起始地址、占用长度,同时修改未分配区表中空闲区的长度和起始地址。当作业撤离时,已分配区表中的相应状态变为空,而将收回的分区登记到未分配区表中,若有相邻空闲区,将其合并后登记。
已分配分区表和未分配分区表采用链表是不错的选择。在内部各分区都可按一定的规则排列。如按空闲区大小、地址排列。
常用的可变分区分配算法有以下五种:
1:先适应分配算法:顺序查找未分配表找出一个满足需要的。
2:下次适应分配算法:总是从未分配区的上次扫描结束处顺序查找未分配区表。
3:优适应分配算法:扫描整个未分配区表,从中找出一个能满足需要的小分区进行分配。查找前分区一般按大小排列。
4:坏适应分配算法:扫描整个未分配分区表,总是挑选一个大的空闲区分割给作业使用。
5:快速适应分配算法:为那些经常使用的长度设立单独的空闲区链表。
对可变分区需采用动态地址重定位,进程的程序和数据的地址转换由硬件完成,硬件设置两个专用控制寄存器:基址寄存器和限长寄存器。基址寄存器存放分配给进程使用的分区的起始地址,限长寄存器存放进程所占用的连续存储空间的长度。当进程占有cpu运行后,操作系统可把分区的起始地址和长度送入基址寄存器和限长寄存器,在执行指令或访问数据时,由硬件根据基址寄存器进行地址转换得到地址。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11