本文共 7912 字,大约阅读时间需要 26 分钟。
早期计算机
中,早期计算机主存容量远比现在的要小,主存虽然仅存放一道用户程序,但存储空间放不下用户进程
的现象经常发生,而覆盖技术就可以解决这种矛盾。由于程序运行时并非任何时候都要访问程序及数据的各个部分,因此可以将用户空间分成一个固定区和若干覆盖区。将经常活跃的部分放在固定区,其余部分按调用关系分段;将那些即将要访问的段放入覆盖区,其他段放在外存中,在需要的时候调入覆盖区,覆盖覆盖区原有的段
。打破了必须将一个进程的全部信息装入主存后才能运行的限制
,但当同时运行程序的代码量大于主存时仍不能运行,此外,内存能够更新的只有覆盖区的段,不在覆盖区的段会常驻内存。将处于等待状态或在 CPU 调度原则下被剥夺运行权力的程序从内存移到辅存以腾出内存空间,此过程称为换出;把准备好竞争处理机的程序从辅存移到内存,此过程称为换入
。理想情况下,内存管理器的交换过程速度足够快,总有进程在内存中可以执行。备份存储
,通常是快速磁盘
——必须足够大,并提供对这些内存映像的直接访问。 · 为有效使用 CPU,需使每个进程的执行时间比交换时间长
,而影响交换时间的主要是转移时间
。转移时间与所交换的内存空间成正比
。 · 若换出进程,则必须确保该进程完全处于空闲状态
。 · 交换空间通常作为磁盘的一整块
,且独立于文件系统
。 · 交换通常有许多进程运行且内存空间吃紧时开始启动,而在系统负荷降低时就暂停。 · 普通的交换使用不同,但交换策略的某些变体在许多系统中,如 UNIX 系统中仍发挥作用。交换技术主要在不同进程或作业之间进行,而覆盖则用于同一个程序或进程中
。由于覆盖技术要求给出程序段之间的覆盖结构,使得其对用户和程序员不透明,所以对于主存无法存放用户程序矛盾,现代操作系统是通过虚拟内存技术来解决的,覆盖技术则已成为历史;而交换技术在现代操作系统中仍具有较强生命力。连续分配管理方式
和非连续分配管理方式
两种。指为一个用户程序分配一个连续的内存空间
;而非连续分配管理方式则允许将一个程序分散地装入不相邻地内存分区
。单一连续分配
、固定分区分配
和动态分区分配
。将内存划分为系统区和用户区
,系统区仅供操作系统使用,通常在低地址部分
;用户区为用户提供的、除系统区外的内存空间。由于内存中永远只有一道程序,因此不会出现访问越界干扰其他程序的情况,故而无需进行内存保护。简单、无外部碎片,可采用覆盖技术,无需额外技术支持
。只能用于单用户、单任务的操作系统中,有内部碎片,存储器利用率极低
。多道程序存储管理
方式。将用户内存空间划分为若干固定大小的内存区,每个分区只装入一道作业;每当有空闲分区,便从外存的后备作业队列中选择适当大小的作业装入该分区,如此循环
。分区大小相等和分区大小不等
。前者用于利用一台计算机去控制多个相同对象的场合,缺乏灵活性;后者将内存划分为多个较小的分区、适量的中等分区和少量大分区。如下图: 为便于内存分配,将分区按大小排队,并建立分区说明表,表项由分区的起始地址、大小及状态构成
。每当有用户程序要装入时,检索分区说明表,寻找合适的分区并将其对应分区的状态设置为“已分配”,若没有合适的分区,则拒绝为用户程序分配内存。分区说明表和存储空间分配情况如下图: 程序可能太大放不进任何一个分区,此时用户不得不用覆盖技术使用内存空间
。 ② 主存利用率低,当程序小于固定分区时,也占用一个完整的分区,这样分区内部存在空间浪费,此种现象称为内部碎片
。可变分区分配
,是一种动态规划内存的分区方法。不预先划分内存,而是在进程装入内存时,根据进程大小动态地建立分区,并使分区大小正适合进程的需要
。故而,系统分区的大小和数目是可变的。随着时间的推移,内存中会出现越来越多的小内存块,也就是所谓的外部碎片——指所有分区外的存储空间会变成越来越多的碎片
,与上面固定分区中提及的内部碎片相反;外部碎片的出现,会导致内存利用率降低。紧凑(Compaction)技术
来解决,也就是操作系统不时地对进程进行移动和整理,需要动态重定位寄存器的支持,并且相对费时
。首次适应算法、最佳适应算法、最坏适应算法和邻近适应算法
。空闲分区以地址递增的次序链接
。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区
。空闲分区按容量递增的方式形成分区链,找到第一个能满足要求的空闲分区
。最大适应(Largest Fit)算法
,空闲分区以容量递减得次序链接,找到第一个能满足要求得空闲分区,即挑出最大的空闲分区
。循环首次适应算法
,由首次适应算法演变而来,区别在于,分配内存时从上次查找结束的位置开始继续查找
。用户进程在主存中是连续存放的
。分页存储管理方式和分段存储管理方式
。分页存储管理方式中,又- 根据运行作业时是否要把所有页面都装入内存才能运行,分为基本分页存储管理和请求分页存储管理
。将主存空间划分为大小相等且固定的块,块相对较小,作为主存基本单位,进程以块为单位进行划分,进程在执行时以块为单位逐个申请块空间
。每个进程平均只产生半个块大小的内部碎片,这种碎片称为页内碎片
。进程中的块称为页(Page)
,内存中的块称为页框(Page Frame,或页帧)
,外存也以同样的单位进行划分,直接称块(Block)
。进程申请空间时,为每个页面分配主存中的可用页框,也即页和页框一一对应。出于方便地址转换,页面大小为 2 的整数幂,通常为 512B~8 KB。页面太小会使进程页数过多导致页表过长,占用内存、增加硬件地址转换的开销,从而降低页面换入/换出效率;页面太长,会使页内碎片增大,降低内存利用率;故而页面大小要适中,在空间效率和时间效率之间权衡
。系统为每个进程建立一张页面映像表,称为页表
。页表记录页面在内存中对应的物理块号,一般存于内存中;从页表的内容可以知道,也表示用于寻找进程的每个页面在内存中对应的物理块。每个页表项由页号和物理内存中块号组成
;页表项的块号与地址的位移量构成物理地址
。 地址变换机构借助页表将逻辑地址转换成内存中的物理地址
。 页表寄存器(Page-Table Register,PTR)
,存放页表在内存中的起始地址F和页表长度M。进程未执行时,页表的起始地址和长度存放在进程的 PCB 中,进程执行时,将页表始地址和长度存入页表寄存器。计算页号 P=A/L 和页内偏移量 W=A%L。
② 比较页号 P 和页表长度 M,若 P>=M 则发生越界中断,否则继续执行。
③ 页表中页号 P 对应页表项地址 = 页表始地址 F + 页号 P * 页表项长度,取出该页表项内容 b,即为物理块号。
注意:页表长度指一共有多少页,页表项长度指页地址占据多大存储空间
。 ④ 计算 E=b*L+W,得到物理地址 E 去访问内存。
① 每次访存都需要进行逻辑地址到物理地址的转换,地址转换过程必须足够快,否则会降低访存速度
。
每个进程引入页表,用于存储映射机制,页表不能太大,否则降低内存利用率
。 地址变换机构中增设一个具有并行查找能力的高速缓冲存储器——快表
,也叫相联存储器(Translation Look aside Buffer,TLB)
,存放当前访问的若干页表项,加速地址变换过程;与此相对,主存中的页表称为慢表。 CPU 给出逻辑地址,由硬件进行地址转换,将页号送入高速缓寄存器,将此页号与快表中的所有页号比较
。 ② 若找到匹配的页号,则直接从高速缓存寄存器中取出对应的页框号,与页内偏移量组成物理地址;这样,一次访存就可以取出数据
。 ③ 若没有找到匹配的页号,则访问主存中的页表,读出页表项后,将其存入快表,便以后面可能的再次访问;调入新的页表项时,若快表已满,则需要按照一定的算法对旧的快表项进行替换
。将页表再分页并离散地存储在不同的物理块中,并为离散分配地页表再建立一张页表,称为外层页表(Outer Page Table),外层页表地页表项记录了页表页面地物理块号
。外层页表又称作一级页表,内层页表也就是二级页表。此时逻辑地址结构如下: 外层页表寄存器
存放外层页表的始址,并利用逻辑地址中的外层页号作为外层页表的索引
,从中找到指定页表分页的始址,再利用二级页号(外层页内地址)作为指定分页的索引找到指定的页表项
,其中就含有该页在内存中的物理块号,用该块号与页内地址构成物理地址。 建立多级页表的目的在于建立索引,以便不用浪费主存空间去存储无用的页表项,也不用盲目地顺序查找页表项
。不过,如上做法还未解决用较少地内存空间去存放大页表地问题。为此,需要进一步的措施。在采用两级页表的情况下,对于正在运行的进程,必须将其外层页表调入内存
,而对页表只需调入一页或几页;为了确定某页是否已经调入内存,还应在外层页表中增设一个状态位 S
,1 表示已经调入,0 表示未调入;进程运行时,地址变换机构根据逻辑地址中的外部页号,去查找外层页表,若所找到的页表项状态位为 0,则产生中断信号,请求操作系统将该页表分页调入内存。分段管理方式则是考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要
。 作业或进程的地址空间被划分为若干段,每段定义了一组逻辑信息
;一般按照进程的自然段来划分
,例如进程由一个主程序、两个子程序、栈和一段数据组成,那么便可以划分为主程序段MAIN、子程序段X、子程序段Y、栈段S和数据段D。虽然每个段都有段名,但是为方便通常用段号替代段名,每段从 0 开始编址,并采用一段连续的地址空间;段长由段的逻辑信息决定,故而各段段长并不一致,同理整个进程或作业有多少段也是动态的。 整个作业的逻辑地址由段号和段内地址组成: 而段式存储管理方式下,段号和段内偏移量必须由用户提供,高级程序设计语言中,这个工作由编译程序完成,编译程序能自动根据源程序的情况而产生若干段
。系统也为每个进程建立一张段映射表,即段表。段表项为进程一个段在内存中的起始地址(基址)和段长
。段表内容如下: 从逻辑地址 A 取出段号 S,段内偏移量 W
。 ② 比较段号 S 和段表长度 M,若 S>=M,产生越界中断,否则继续执行
。 ③ 段表中段号为营的段表项始地址=段表始址F+段号S*段表项长度,取出对应段表项的段长C。若段内偏移量>=C,则发生越界中断,否则继续执行
。 ④ 取出段表项中该段的始址b,计算E=b+W 形成物理地址,然后根据物理地址去访存
。段的共享通过两个作业的段表中相应表项指向共享的段的同一个物理副本来实现
。当一个作业正从共享段读取数据时,必须防止另一个作业修改此共享段的数据。不能修改的代码称为纯代码或可重入代码,这不属于临界资源,这样的代码和不能修改的数据可以共享,而可以修改的代码和数据不能共享。存取控制保护
② 地址越界保护
所谓越界保护是将段表寄存器中的段表长度与逻辑地址中的段号比较,若段号大于段表长度,则产生越界中断
;再将段表项中的段长和逻辑地址中的段内偏移量进行比较,若段内偏移量大于段长,也会产生越界中断。分页管理中的地址越界只需判断页号是否越界,而页内偏移量是不可能越界的。作业的地址空间首先被划分为若干逻辑段,每段有自己的段号,然后将每个段分成若干大小固定的页
。内存管理方式和分页存储管理一样,将其分成若干和页面大小相同的存储块,对内存的分配以存储块为单位
。段页式系统中,作业的逻辑地址分为段号、页号和页内偏移量(页内地址)
: 首先通过段表查到页表始地址,然后通过页表找到页帧号,最后形成物理地址
。如上图所示,进行一次访问实际需要三次访问主存,因此同样可以使用快表来加快查找速度,其关键字由段号、页号组成,值是对应的页帧号和保护码。段页式管理的地址空间也是二维的。转载地址:http://uqqgn.baihongyu.com/