物理地址:又称绝对地址,即程序执行所使用的地址空间(处理器执行指令时按照物理地址进行)
逻辑地址:又称相对地址,即用户编程所使用的地址空间,从0开始编号,有两种形式:一维逻辑地址(地址)
二维逻辑地址(段号:段内地址)
主存储器空间等分配与去配:
分配:进程装入主存时,存储管理软件进行具体的主存分配操作,并设置一个表格记录主存空间的分配情况
去配:当某个进程撤离或主动归还主存资源时,存储管理软件要收回它所占用的全部或者部分存储空间,调整主存分配表信息
主存储器空间的共享:
多个进程共享主存储器资源:多道程序设计技术使若干个程序同时进入主存储器,各自占用一定数量的存储空间,共同使用一个主存储器
多个进程共享主存储器的某些区域:若干个协作进程有共同的主存程序块或者主存数据块
多道程序设计需要复用主存:
按照分区复用:主存划分为多个固定/可变尺寸的分区,一个程序/程序段占用一个分区
按照页架复用:主存划分成多个固定大小的页架,一个程序/程序段占用多个页架
地址转换:又称重定位,即把逻辑地址转换成绝对地址,可分为:
静态重定位:在程序装入内存时进行地址转换,在装入一个作业时,把该作业中程序的指令地址和数据地址全部转换成绝对地址,由装入程序执行,早期小型OS使用
动态重地位:在CPU执行程序时进行地址转换,从效率出发,依赖硬件地址转换机构
存储保护:为避免主存中的多个进程相互干扰,必须对主存中的程序和数据进行保护。这一功能需要软硬件协同完成,CPU检查是否允许访问,不允许则产生地址保护异常,由OS进行相应处理。
数据段可指定R/W或RO;程序段可指定R/E或RO
私有主存区中的信息可读可写
公共区中的共享信息需根据授权
非本进程信息、未获授权的信息(如OS内核、页表等)不可读写
以下情况会发生存储保护错:
访问越权(访问操作与所拥有的访问权限不符):页表中设定访问(存取)权限
地址越界(转换得到的物理地址不属于可访问范围)
为了对操作系统的存储保护提供支持,硬件必须具有以下三种基本功能:
支持至少2种运行模式
管理模式:执行系统程序(内核)时处理器所处的模式,或称管理程序模式,简称管态、管理态、核心态、内核态
用户模式:CPU执行非操作系统的用户程序时,处理器所处的模式,或称用户状态、目标程序状态,简称目态、用户态
使一部分CPU状态只能由内核程序读写而不能由用户程序读写:User/SuperVisor模式位、页表首地址、TLB等。OS内核可用特殊指令(一般称管态指令、特权指令)来读写
提供让CPU在管理模式和用户模式相互转换的机制:异常和陷阱(系统调用)使CPU从用户态转到内核态;异常处理中的“返回”指令使CPU从内核态转到用户态。
动态重定位、存储保护等,若无硬件支撑在效率上是无意义、无实现价值的。
地址转换/存储保护的硬件支撑图
存储扩充:把磁盘作为主存扩充,只把部分进程或进程的部分内容装入内存
对换技术:把部分不运行的进程调出
虚拟技术:只调入进程的部分内容
这一工作需要软硬件协作完成
对换进程决定对换,硬件机构调入
CPU处理到不在主存的地址,发出虚拟地址异常,OS将其调入,重执指令
虚拟存储器思想的提出:
主存容量限制带来诸多不便:用户编写程序必须考虑主存容量限制、多道程序设计的道数受到限制
用户编程行为分析:全面考虑各种情况,执行时有互斥性;顺序性和循环性等空间局部性行为;某一阶段执行的时间局部性行为
因此可以考虑部分调入进程内容
存储管理把进程全部信息放在辅存中,执行时先将其中一部分装入主存,以后根据执行行为随用随调入。如主存中没有足够的空闲空间,存储管理需要根据执行行为把主存中暂时不用的信息调出到辅存上去
需要建立与自动管理两个地址空间:(辅存)虚拟地址空间容纳进程装入、 (主存)实际地址空间承载进程执行
对于用户,计算机系统具有一个容量大得多的主存空间,即虚拟存储器 ,虚拟存储器是一种地址空间扩展技术,通常意义上对用户编程是透明的,除非用户需要进行高性能的程序设计。
无硬件实现虚拟地址中断,虚拟存储器无法实现。
“主存—辅存”层次与“Cache--主存”层次相比:
页大小(2KB~64KB)比Cache中的Block大得多,采用全相联映射:因为缺页时需要访问磁盘(约几百万个时钟周期),而cache缺失时访问主存仅需几十到几百个时钟周期,开销比Cache缺失开销大的多。因此,页命中率比cache命中率更重要!“大页面”和“全相联”可提高页命中率。
通过软件来处理“缺页”:缺页时需要访问磁盘,慢,不能用硬件实现。
采用Write Back写策略:避免频繁的慢速磁盘访问操作。
地址转换用硬件实现:加快指令执行
存储管理是OS管理主存储器的软件部分
为获得更好的处理性能,部分主存程序与数据(特别是关键性能数据)被调入Cache,存储管理需要对其进行管理,甚至包括对联想存储器的管理
为获得更大的虚拟地址空间,存储管理需要对存放在硬盘、固态硬盘、甚至网络硬盘上的虚拟存储器文件进行管理
存储管理的基本模式可分为:
单连续存储管理:一维逻辑地址空间的程序占用一个主存固定分区或可变分区
段式存储管理:段式二维逻辑地址空间的程序占用多个主存可变分区
页式存储管理:一维逻辑地址空间的程序占用多个主存页架区
段页式存储管理:段式二维逻辑地址空间的程序占用多个主存页架区
单连续存储管理
每个进程占用一个物理上完全连续的存储空间(区域)
单用户连续存储管理
主存区域划分为系统区与用户区。设置一个栅栏寄存器界分两个区域,硬件用它在执行时进行存储保护。
一般采用静态重定位进行地址转换。
硬件实现代价低,适用于单用户单任务操作系统,如DOS。
固定分区存储管理
支持多个分区,分区数量固定、大小固定。
可用静态/动态重定位。
存储保护一定是由硬件来做。
硬件实现代价低,一般为早期OS采用。
根据主存分配表进行主存分配与去配
硬件实现机制与动态重定位如图:
可变分区存储管理
固定分区存储管理不够灵活,既不适应大尺寸程序,又存在内存内零头,有浪费。
按照进程实际内存需求动态划分分区,创建一个进程时,根据进程所需主存量查看主存中是否有足够的空闲空间,若有,则按需要量分割一个分区;若无,则令该进程等待主存资源。由于分区大小按照进程实际需要量来确定,因此分区个数是随机可变的。
但可变分区方式也会随着进程的内存分配产生一些小的不可用的内存分区,称为内存外零头。
根据已分配区表和未分配区表进行主存分配与去配。由于分区数量动态调整,起址也是动态可变的,因此两张表一定链接成链表。
硬件实现机制与动态重定位如图:
可变分区方式的内存分配可算法有:
最先适应(first fit)分配算法:空闲区表按照内存起址先后组织成链表,总是在最前面找一个足够的分区予以分配
邻近适应(next fit)分配算法:把空闲区表组织成循环的队列进行分配
最优适应(best fit)分配算法:按照分区大小组织成队列,找一个最小的能够容纳该进程的分区予以分配。最容易产生外零头。
最坏适应(worst fit)分配算法
快速适应(quick fit)分配算法:该算法为那些经常用到的长度的空闲区设立单独的空闲区链表。此算法查找十分快速,只要按照进程长度直接搜索能容纳它的最小空闲区链表并取第一块分配,但归还内存空间时与相邻空闲区的合并复杂费时,而且存在一定空间浪费。
前四个为顺序搜索法,快速适应算法又称为分类搜索算法。
任何适配算法都不能避免产生外零头,可以采用移动技术(程序浮动技术)移动分区以解决内存外零头(需要动态重定位支撑)。
页式存储管理
分页存储器将主存划分成多个大小相等的页架,受页架尺寸限制,程序的逻辑地址也自然分成页。不同的页可以放在不同页架(不需要连续)中。
页式存储管理的逻辑地址由两部分组成,逻辑地址形式为页号:单元号
页式存储管理的物理地址也由两部分组成:形式为页架号:单元号
地址转换可以通过查页表完成。
管理空闲主存空间:可用一张位示图来记录主存分配情况。为每一个页架建立一个位来记载是否被占用(不需要记载被哪个进程占用);并记录主存剩余的空闲块数。
页式存储管理能够实现多个进程共享程序和数据
数据共享:不同进程可以使用不同页号共享数据页
程序共享:不同进程必须使用相同页号共享代码页,共享代码页中的JMP <页内地址>指令,使用不同页号做不到
页表放在主存,每次地址转换必须访问多次主存,先按页号读出页表中的相应页架号,再按计算出来的绝对地址进行读写,降低了存取速度。因此可以利用Cache存放部分页表。设置一个专用的高速存储器,用来存放TLB/快表,这种高速存储器是联想存储器,即按照内容寻址,而非按照地址访问。
TLB全相联时,TLB中的页表项没有index,只有Tag,页号需与每个Tag比较;
TLB组相联时,则页号高位为Tag,低位为index,用作组索引。
基于快表的地址转换流程为:
按逻辑地址中的页号查快表
若该页已在快表中,则由页架号和单元号形成绝对地址
若该页不在快表中,则再查主存页表形成绝对地址,同时将该页登记到快表中
当快表填满后,又要登记新页时,则需在快表中按一定策略淘汰一个旧登记项
多道程序环境下需要有进程表登记每个进程的页表。
每个进程有一个页表用于维系进程的主存完整性。进程占有处理器运行时,其页表起始地址和页表长度送入页表控制寄存器。
页式虚拟存储管理:把进程全部页面装入虚拟存储器,执行时先把部分页面装入实际内存,然后,根据执行行为,动态调入不在主存的页,同时进行必要的页面调出,是现代OS的主流存储管理技术。
首次只把进程第一页信息装入主存,称为请求页式存储管理
需要扩产页表项,其中有装入位、修改(Dirt)位、替换控制位、访问权限位、禁止缓存位、页架号。
一个页表的项数=虚拟地址空间大小/页大小。
(1)未分配页:进程的虚拟地址空间中“空洞”对应的页(如VP0、VP4)
(2)已分配的缓存页:有内容对应的已装入主存的页(如VP1、VP2、VP5等)
(3)已分配的未缓存页:有内容对应但未装入主存的页(如VP3、VP6)
CPU处理地址,若页驻留,则获得块号形成绝对地址;
当装入位V=0时,页不在内存发生缺页,则CPU发出缺页中断,当前进程被挂起。缺少的页从磁盘读到内存,若内存没有空间,则还要从内存选择一页替换到磁盘上,更新页表与快表,处理结束回到原指令继续执行。替换算法类似于Cache,采用回写法,淘汰时,根据dirty位确定是否要写回磁盘。
当读写操作不符合存取权限(Access Right)时,发生保护违例或访问违例:在屏幕上显示“内存保护错”或“访问违例”信息;当前指令的执行被阻塞,当前进程被终止
缺页中断的处理流程如图:
当主存空间已满而又需要装入新页时,页式虚拟存储管理必须按照一定的算法把已在主存的一些页调出去。选择淘汰页的工作称为页面调度 ,选择淘汰页的算法称为页面调度算法,页面调度算法设计不当,会出现刚被淘汰的页面立即又要调入,并如此反复,这种现象称为抖动或颠簸。
缺页中断率:假定进程P共n页,系统分配页架数m个,P运行中成功访问次数为S,不成功访问次数为F,总访问次数A=S+F,缺页中断率定义为:f=F/A。缺页中断率是衡量存储管理性能和用户编程水平的重要依据。主要受到分配给进程的页架数、页面的大小、用户的程序编制方法的影响。
最佳页面替换算法(OPT):理想的调度算法,只可模拟,不可实现。当要调入新页面时,首先淘汰以后不再访问的页,然后选择距现在最长时间后再访问的页。
先进先出页面调度算法(FIFO):总是淘汰最先调入主存的那一页,或者说主存驻留时间最长的那一页(常驻的除外)。模拟的是程序执行的顺序性,有一定合理性。
最近最少用页面调度算法(LRU):淘汰最近一段时间较久未被访问的那一页,即那些刚被使用过的页面,可能马上还要被使用到。模拟了程序执行的局部属性,既考虑了循环性又兼顾了顺序性,但严格实现的代价大(需要维持特殊队列),模拟实现的方法为:每页建一个引用标志,供硬件使用;设置一个时间间隔中断,中断时页引用标志置0;地址转换时,页引用标志置1;淘汰页面时,从页引用标志为0的页中间随机选择。不过时间间隔多长是个难点。
最不常用页面调度算法(LFU):淘汰最近一段时间内访问次数较少的页面,对OPT的模拟性比LRU更好。模拟实现的方法为:基于时间间隔中断,并给每一页设置一个计数器;时间间隔中断发生后,所有计数器清0;每访问页1次就给计数器加1;选择计数值最小的页面淘汰。
时钟页面替换算法(Clock):采用循环队列机制构造页面队列,形成了一个类似于钟表面的环形表。队列指针则相当于钟表面上的表针,指向可能要淘汰的页面。使用页引用标志位。页面调入主存时,其引用标志位置1;访问主存页面时,其引用标志位置1;淘汰页面时,从指针当前指向的页面开始扫描循环队列,把所遇到的引用标志位是1的页面的引用标志位清0,并跳过;把所遇到的引用标志位是0的页面淘汰,指针推进一步。
页表及相关硬件机制在地址转换、存储保护、虚拟地址访问中发挥了关键作用
为页式存储管理设置专门硬件机构内存管理单元MMU:CPU管理虚拟/物理存储器的控制线路,把虚拟地址映射为物理地址,并提供存储保护,必要时确定淘汰页面
反置页表IPT:MMU用的数据结构
针对内存中的每个页架建立一个页表,按照块号排序(页表式按照页号做索引记的是页架号,反置页表则按照页架号做索引记进程号和页号),用来完成内存页架到访问进程、页号的对应,即物理地址到逻辑地址的转换
表项包括:
页号:虚拟地址页号
进程标志符:使用该页的进程号(页号和进程标志符结合起来标志一个特定进程的虚拟地址空间的一页
标志位:有效、引用、修改、保护和锁定等标志信息
链指针:哈希链
基于反置页表的地址转换的过程为:
MMU通过哈希表把进程标识和虚页号转换成一个哈希值,指向IPT的一个表目
MMU遍历哈希链找到所需进程的虚页号,该项的索引就是页架号,通过拼接位移便可生成物理地址
若遍历整个反置页表中未能找到匹配页表项,说明该页不在内存,产生缺页中断,请求操作系统调入
选择淘汰页面在图中未显示,同样由MMU完成。
段式存储管理
段式程序设计:把一个程序设计成多个段(代码段、数据段、堆栈段等),用户可以自己应用段覆盖技术扩充内存空间使用量。每一段都可以从“0”开始编址,段内的地址是连续的。分段存储器的逻辑地址由段号:单元号组成。
这一技术是程序设计技术,不是OS存储管理的。段号和单元号是用户程序自己设计的,用户可控制,而页号和单元号是系统切割的用户不知道。
段式存储管理基于可变分区存储管理实现,一个进程要占用多个分区,硬件需要增加一组用户可见的段地址寄存器(代码段、数据段、堆栈段,附加段),供地址转换使用;存储管理需要增加设置一个段表,每个段占用一个段表项,包括:段始址、段限长,以及存储保护、可移动、可扩充等标志位。
通过不同进程段表中的项指向同一个段基址来实现段的共享。对共享段的信息必须进行保护,如规定只能读出不能写入,不满足保护条件则产生保护中断。
段式虚拟存储管理:把进程的所有分段都存放在辅存中,进程运行时先把当前需要的一段或几段装入主存,在执行过程中访问到不在主存的段时再把它们动态装入。段式虚拟存储管理中段的调进调出是由OS自动实现的,对用户透明,而段覆盖技术则是用户控制的主存扩充技术,OS不感知。
段式虚拟存储管理需要进行段表的扩充
特征位: 00(不在内存)01(在内存)11(共享段)
存取权限: 00(可执行)01(可读)11(可写)
扩充位: 0(固定长)1(可扩充)
标志位: 00(未修改)01(已修改)11(不可移动)
段页式存储管理
段式存储管理可以基于页式存储管理实现,每一段不必占据连续的存储空间,可存放在不连续的主存页架中
段表不再记录基址与限长,而是记录页表的基址与限长
每一段有一个页表。逻辑地址由段号:段内页号:页内偏移地址构成
还可以扩充为段页式虚拟存储管理,装入部分段,或者装入段中部分页面