OS复习——存储管理

OS复习——存储管理

1. 存储管理的功能

  • 内存的分配与回收
    • 内存的分配有静态的分配、动态的分配。(什么时候要静态的分配,什么时候要动态的分配)
    • 要理解地址空间和存储空间的概念
      • 地址空间:一个进程所能够用于访问内存的地址(逻辑地址)的集合
      • 存储空间:计算机物理内存中的实际地址(物理地址)的集合
  • 存储保护:多个程序在内存中运行,必须保证它们之间不能相互冲突、相互干扰和相互破坏。存储保护的内容包括地址越界保护(每个进程都具有其相对独立的地址空间)和权限保护(对于允许多个进程共享的公共区域,每个进程都有自己的访问权限)。
  • 地址变换:把逻辑地址转换成绝对地址。
  • 静态重定位:在程序执行之前进行重定位,根据装配模块将要装入的内存起始位置直接修改装配模块中的有关使用地址的指令。
  • 动态重定位:在程序执行过程中进行地址重定位,在每次访问内存单元前才进行地址转换,可使装配模块不加任何修改而装入内存。
  • 存储共享:多个进程动态地共享内存和内存中某个区域的信息,共享的内容包括代码共享和数据共享。
  • ”扩充“内存容量:利用存储管理软件为进程提供一个比实际内存更大的逻辑存储空间,即虚拟存储管理技术。

2. 分区存储管理

分区式分配:把内存分为一些大小相等或不等的分区,每个应用程序占用一个或几个分区。操作系统占用其中一个分区。适用于多道程序系统和分时系统,支持多个程序并发执行,但难以进行内存分区的共享。

2.1 固定分区

2.1.1 基本思想

​ 系统先把内存划分为若干个大小固定的分区,一旦划分好,在系统运行期间便不再重新划分。

  • 分区大小相等:只适合于多个相同程序的并发执行(处理多个类型相同的对象)。
  • 分区大小不等:多个小分区、适量的中等分区、少量的大分区。根据程序的大小,分配当前空闲的、适当大小的分区。

2.1.2 优缺点

  • 优点:易于实现,开销小。
  • 缺点:内碎片造成浪费,分区总数固定,限制了并发执行的程序数目。

2.2 可变分区

2.2.1 基本思想

​ 系统不预先划分固定分区,而是在装入程序时划分内存分区,使为程序分配的分区的大小正好等于该程序的需求量,且分区的个数是可变的。

2.2.2 优缺点

  • 优点:没有内碎片。
  • 缺点:有外碎片。

2.2.3 主要算法(基于顺序搜索的分配算法)

  • 首次适应算法(FirstFit)
    • 算法思想:每个空闲区按其在存储空间中地址递增的顺序连在一起,在为作业分配存储区域时,从这个空闲区域链的始端开始查找,选择第一个足以满足请求的空白块。
    • 算法特点:优先利用内存低地址部分的空闲分区。但由于低地址部分不断被划分,留下许多难以利用的很小的空闲分区(碎片或零头) ,而每次查找又都是从低地址部分开始,增加了查找可用空闲分区的开销。
  • 下次适应算法(NextFit)
    • 算法思想:把存储空间中空闲区构成一个循环链表,每次为存储请求查找合适的分区时,总是从上次查找结束的地方开始,只要找到一个足够大的空闲区,就将它划分后分配出去。
    • 算法特点:使存储空间的利用更加均衡,不致使小的空闲区集中在存储区的一端,但这会导致缺乏大的空闲分区。
  • 最佳适应算法(BestFit)
    • 算法思想:为一个作业选择分区时,总是寻找其大小最接近于作业所要求的存储区域。
    • 算法特点:若存在与作业大小一致的空闲分区,则它必然被选中,若不存在与作业大小一致的空闲分区,则只分配比作业稍大的空闲分区,从而保留了大的空闲分区。最佳适应算法往往使剩下的空闲区非常小,从而在留下许多难以利用的小空闲区(碎片) 。
  • 最坏适应算法(WorstFit)
    • 算法思想:为作业选择存储区域时,总是寻找最大的空闲区。
    • 算法特点:总是挑选满足作业要求的最大的分区分配给作业。这样使分给作业后剩下的空闲分区也较大,可装下其它作业。由于最大的空闲分区总是因首先分配而划分,当有大作业到来时,其存储空间的申请往往会得不到满足。

2.3 覆盖与交换

2.3.1 分区管理的问题

​ 大作业在小内存中运行的问题。覆盖与交换技术是在多道程序环境下用来“扩充”内存容量和提高内存利用率的两种方法。覆盖技术主要用在早期的OS中,交换技术则用在现代OS中。

2.3.2 覆盖

​ 把一个程序划分为一系列功能相对独立的程序段,让执行时不要求同时装入内存的程序段组成一组(称为覆盖段),共享主存的同一个区域。程序段先保存在磁盘上,当有关程序段的前一部分执行结束,把后续程序段调入内存,覆盖前面的程序段(内容“扩大”了)。缺点是对用户不透明,增加了用户负担。

在这里插入图片描述

2.3.3 交换

​ 把暂时不用的某个(或某些)程序及其数据的部分或全部从主存移到辅存中去,以便腾出存储空间;接着把指定程序或数据从辅存读到相应的主存中,并将控制转给它,让其在系统上运行。

​ 优点是增加并发运行的程序数目,并且给用户提供适当适当的响应时间;编写程序时不影响程序结构。

​ 缺点是对换入和换出的控制增加处理机开销;程序整个地址空间都进行传送,没有考虑执行过程中地址访问的统计特性。

2.3.4 覆盖与交换技术的区别

  • 覆盖可减少一个程序运行所需的空间。交换可让整个程序暂存于外存中,让出内存空间。
  • 覆盖是由程序员实现的,操作系统根据程序员提供的覆盖结构来完成程序段之间的覆盖。交换技术不要求程序员给出程序段之间的覆盖结构。
  • 覆盖技术主要对同一个作业或程序进行。交换主要在作业或程序间之间进行。

3. 页式存储管理

分页存储管理的基本思想是把一个逻辑地址连续的程序分散存放到若干不连续的内存区域内,并保证程序的正确执行。

3.1 页面、页框

  • 页面:把每个作业的地址空间分成一些大小相等的片,称之为页面或页,各页从0开始编号。
  • 页框:把物理内存的存储空间也分成与页面相同大小的片,这些片称为页框或存储块,同样从0开始编号。
  • 纯分页系统优点:
    • 没有外碎片,每个内碎片不超过页大小
    • 一个程序不必连续存放
    • 便于改变程序占用空间的大小

3.2 地址转换

3.2.1 地址转换机制

  • 已知逻辑地址求页号和页内地址:如果逻辑地址空间为2m,且页大小为2n单元,那么逻辑地址的高m-n位表示页号(页表的索引),而低n位表示页偏移。
  • 关于页表:页表存放在内存中,用来记录进程的内存分配情况和实现进程运行时的动态重定位。访问一个数据需访问内存2次(页表一次,内存一次)。页表的基址及长度由页表寄存器给出。
  • 地址变换机构
    • 当进程要访问某个逻辑地址中的数据时,分页地址变换及机构会自动地将相对地址分为“页号”和“页内地址”两部分。
    • 当“页号”与“页表长度”进行比较,如果页号大于或等于页表长度,则表示本次所访问的地址已超越进程的地址空间,产生地址越界中断。
    • 将**“页表始址”“页号和页表项长度的乘积”相加,得到该页表项在页表中的位置**,于是可从页表项中得到该页的物理块号,将之装入物理地址寄存器中。
    • 将相对地址寄存器中的“页内地址”送入物理地址寄存器的“块内地址”字段中。

3.2.2 页表

​ 为了便于在内存找到进程的每个页面所对应的页框,分页系统为每个进程配置一张页表。进程逻辑地址空间中的每一页,在页表中都对应有一个页表项

  • 多级页表(以二级页表为例)

    • 二级页表:将页表再进行分页,离散地将各个页表页面存放在不同的物理块中,同时也再建立一张外部页表用以记录页表页面对应的物理块号。页表项存储的是对应页面的页框号及标志位。

在这里插入图片描述

  • 多级页表:多级页表结构中,指令所给出的地址除偏移地址之外的各部分全是各级页表的页表号或页号,而各级页表中记录的全是物理页号,指向下级页表或真正的被访问页。
    在这里插入图片描述

  • 杂凑页表(哈希页表)

    • 页表实现:使用虚拟页号作为哈希值,哈希页表的每一个表项都包含一个链表,该链表中元素的哈希值都指向同一个位置。每个元素有3个字段:(a)虚拟页号、(b)所映射的页框号、©指向链表中下一个元素的指针。
    • 算法实现:虚拟地址中的虚拟页号转换为哈希表号,用虚拟页号与链表中的每一个元素的字段(a)相比较。如果匹配,那么字段(b)用来形成物理地址;如果不匹配,则沿链表依次寻找相匹配的元素。

在这里插入图片描述

  • 反置页表

    • 页表实现:反置页表中的页表项按物理页框号排列,其页表项的内容是逻辑页号P及拥有该页面的进程标识符pid。(整个系统中只存在一个页表)

在这里插入图片描述

  • 算法实现:用进程标志符和页号去检索反置页表。如果检索完整个页表未找到与之匹配的页表项,表明此页此时尚未调入内存,对于具有请求调页功能的存储器系统产生请求调页中断,若无此功能则表示地址出错。如果检索到与之匹配的表项,则表项的序号 i 便是该页的物理块号,将该块号与页内地址一起构成物理地址。

在这里插入图片描述

  • 页表改进:反置页表按照物理地址排序,而查找依据虚拟地址,所以可能需要查找整个表来寻找匹配。可以使用哈希页表限制页表条目或加入 TLB 来改善。通过哈希表查找可由逻辑页号得到物理页面号。虚拟地址中的逻辑页号通过哈希表指向反置页表中的表项链头(因为哈希表可能指向多个表项),得到物理页面号。但采用反置页表的系统很难共享内存,因为每个物理页框只对应一个页表项。

在这里插入图片描述

3.2.3 快表(TLB)

​ TLB通常被安装在MMU的内部,实质上就是页表的高速缓存,每个TLB条目中包含一个页面的所有信息(有效位、虚页号、物理页号、修改位、保护位等等),这些条目中的内容和页表中相同页面的条目中的内容是完全一致的。

​ 当一个虚拟地址被送到MMU中进行翻译的时候,硬件首先在TLB中寻找包含这个地址的页面,如果它的虚页号在TLB中,并且没有违反保护位,那么就可以直接从TLB中得到相应的物理页号,而不去访问页表;如果发现虚页号在TLB中不存在,那么MMU将进行常规的页表查找,同时通过一定的策略来将这一页的页表项替换到TLB中,之后再次访问这一页的时候就可以直接在TLB中找到。

在这里插入图片描述

​ 有的TLB在每个TLB条目中还保存地址空间标识码(ASID)。ASID可用来唯一标识进程,并为进程提供地址空间保护。当TLB试图解析虚拟页号时,它确保当前运行进程的ASID与虚拟页相关的ASID相匹配。如果不匹配,那么就作为TLB失效。除了提供地址空间保护外,ASID允许TLB同时包含多个进程的条目。

3.2.4 页面的大小

  • 页大小是由硬件来决定的,通常为2的幂
  • 选择页的大小为2的幂可以方便地将逻辑地址转换为页框号和页偏移。
  • 现在操作系统中,最常用的页面大小是4KB
  • 若页面较小
    • 减少页内碎片和总的内存碎片,有利于提高内存利用率
    • 每个进程页面数增多,使页表长度增加,占用内存较大
    • 页面换进换出速度将降低
  • 若页面较大
    • 每个页面数减少,页表长度减少,占用内存较小
    • 页面换进换出速度将提高
    • 增加页内碎片,不利于提高内存利用率

3.3 页目录自映射

​ 以32位二级页表系统为例,内存空间为4G,每个页面是4KB,共有1M个页面,每个页面对应一个页表项,每个页表项需要4字节。

​ 存储页表的4MB地址空间是整个4GB虚拟地址空间中的一部分,一方面根据页目录的定义,记录这4MB连续地址空间到物理地址空间映射关系的,是一个4KB的页目录;另一方面根据页表页的定义,记录这4MB连续地址空间到物理地址空间映射关系的,是一个4KB的页表页。所以,页目录和上述页表页内容相同,页目录无需额外分配单独的存储空间。

在这里插入图片描述

页目录自映射页目录中有一条页目录项指向自身物理地址,自映射页目录项PDEself-mapping所存的物理页号正是页目录所在物理页。

页表基址PTbase,该基址需4MB对齐,PTbase=((PTbase)>>22)<<22(低22位全为0)。

​ 易知,4M空间的起始位置也就是第一个二级页表,对应着页目录的第一个页目录项,页目录基地址PDbase,PDbase=PTbase|((PTbase>>12) * 4)自映射目录表项PDEself-mapping=PTbase|((PTbase>>12) * 4)|((PTbase>>22) * 4) 。所以只要给定4M对齐的页表基址(虚拟地址),就可以得到所有页表项对应的地址,也就包括页目录表基址和自映射页目录项在页目录表中的位置。

4. 段式存储管理

4.1 基本思想

​ 页式分区容易出现碎片,而且页式系统中中一页或页号相连的几个虚页上存放的内容一般都不是一个逻辑意义完整的信息单位。请调一页,可能只用到页中的一片部分内容,不便于数据共享和保护。出于方便编程、信息共享和保护、满足程序运行时对内存的动态增长和链接需求等动机为此提出了段式存储管理技术。

​ 一个段可定义为一组逻辑信息,每个作业的地址空间是由一些分段构成的(由用户根据逻辑信息的相对完整来划分),如代码分段、数据分段、栈段等组成,每段都有自己的名字(通常是段号),且都是一段连续的地址空间,它是用户在编程时决定的。

4.2 地址变换

段表记录了段与内存位置的对应关系,段表保存在内存中,段表的基址及长度由段表寄存器给出。访问一个字节的数据/指令需访问内存两次(段表一次,内存一次),逻辑地址由段号和段内地址。

​ 将逻辑地址中的段号S与段表长度TL进行比较。若S>TL,表示访问越界,产生越界中断;若未越界,则根据段表的始址和该段的段号,计算出该段对应段表项的位置,从中读出该段在内存的始址。再检查段内地址d是否超过该段的段长SL,若超过,即d>SL,同样发出越界中断信号;若未越界,则将该段的基址与段内地址d相加,即可得到要访问的内存物理地址。

在这里插入图片描述

4.3 分页与分段的比较

在这里插入图片描述

​ 分页对用户是透明的,是系统对于主存的管理。分段是用户可见的(分段可以在用户编程时确定,也可以在编译程序对源程序编译时根据信息的性质来划分)。

4.4 段页式内存管理

4.4.1 基本原理

​ 段页式系统的基本原理是分段与分页原理的结合。即先将用户程序分为若干个段,并为每个段赋予一个段名,再把每个段划分为若干页。如图所示为一个作业地址空间的结构,该作业有三个段,页面大小为4KB。

在这里插入图片描述

​ 在段页式系统中,其地址结构由段号、段内页号级页内地址三部分所组成。

在这里插入图片描述

​ 系统中设段表和页表,均存放于内存中。读一次指令或数据须访问内存三次。为提高速度可增设高速缓存。每个进程一张段表,每个段一张页表。段表含段号页表始址页表长度;页表包含页号页框号

在这里插入图片描述

4.4.2 地址转换

​ 从PCB中取出段表始址及段表长度,装入段表寄存器。

​ 将段号与段表长度进行比较,若段号大于或等于段表长度,产生越界中断。利用段表始址与段号得到该段表项在段表中的位置。取出该段的页表始址和页表长度。

​ 将页号与页表长度进行比较,若页号大于或等于页表长度,产生越界中断。利用页表始址与页号得到该页表项在页表中的位置。取出该页的物理块号,与页内地址拼接得到物理地址。

5. 虚拟存储原理与算法

​ 虚拟存储技术的基本思想是:利用大容量的外存来扩充内存,产生一个比有限的实际内存空间大得多的、逻辑的虚拟内存空间,简称虚存。利用虚拟存储技术的操作系统不必将程序全部读入内存,而只需将当前需要执行的部分页或段读入内存,就可让程序开始执行。在程序执行过程中,如果需执行的指令或访问的数据尚未在内存(称为缺页或缺段),则由处理器通知操作系统将相应的页或段从外存调入内存,然后继续执行程序。虚拟存储管理是由操作系统在硬件支持下把两级存储器(内存和外存)统一实施管理,达到“扩充”内存的目的,呈现给用户的是一个远远大于内存容量的编程空间,即虚存

5.1 内存访问的局部性原理

​ 程序执行过程中在一段较短时间内,所执行的指令地址和指令的操作数地址分别局限于一定区域。具体变现为:

  • 时间局部性:即一条指令的一次执行和下次执行,一个数据的一次访问和下次访问都集中在一段较短时间内***或者说***最近被访问的某页,很可能在不久的将来还要访问。支持这种现象:一是循环;二是子程序;三是栈;四是用于计数和总计的变量。
    • 例如:程序中存在很多循环结构,它们由少量指令组成,而被多次执行。
  • 空间局部性:即当前指令和邻近的几条指令,当前访问的数据和邻近的数据都集中在一个较小区域内。支持这种现象:一是数组遍历;二是代码程序的执行;三是程序员倾向于将相关的变量定义相互靠近存放。
    • 例如:程序在执行时,大部分是顺序执行的指令,少部分是转移和过程调用指令。
    • 例如:过程调用的嵌套深度有限,因此执行的范围不超过这组嵌套的过程。
    • 例如:程序中存在很多对特定数据结构的操作,如数组操作,往往局限在较小范围内。

5.2 虚拟存储器

  • 技术特征
    • 离散性:物理内存分配的不连续,虚拟地址空间使用的不连续(数据段和栈段之间的空闲空间,共享段和动态链接库占用的空间)
    • 多次性:作业被分成多次调入内存运行。正是由于多次性,虚拟存储器才具备了逻辑上扩大内存的功能。多次性是虚拟存储器最重要的特征,其它任何存储器不具备这个特征。
    • 对换性:允许在作业运行过程中进行换进、换出。换进、换出可提高内存利用率。
    • 虚拟性:允许程序从逻辑角度访问存储器,而不考虑物理内存上可用的空间容量。
      • 范围大,但占用容量不超过物理内存和外存交换区容量之和。
      • 占用容量包括:进程地址空间中的各个段,操作系统代码。

5.3 页面置换策略

5.3.1 最优置换(OPT算法)

​ 从主存中移出永远不再需要的页面,如这样的页面不存在,则应选择最长时间不需要访问的页面。

5.3.2 先进先出(FIFO算法)

​ 总选择作业中在主存驻留时间最长的一页淘汰。具体实现:新访问的页面插入FIFO队列尾部,页面在FIFO队列中顺序移动;淘汰FIFO队列头部的页面。

​ FIFO算法性能较差。较早调入的页往往是经常被访问的页,这些页在FIFO算法下被反复调入和调出。可能出现Belady异常现象。Belady’s Anomaly是指在使用FIFO是算法作为缺页置换算法时,随着分配的页框增多,缺页率反而提高。

5.3.3 最近最少使用(LRU算法)

​ 该算法是根据一个作业在执行过程中过去的页面踪迹来推测未来的情况。过去一段时间里不曾被访问过的页,在最近的将来可能也不再会被访问。所以当需要淘汰一页时,应选取在最近一段时间内最久未用过的页面予以淘汰。

​ 软件实现:设置一个链表,链表节点保存当前使用的页面的页号。每当有一次内存访问(读/写),根据相应的页面号查找链表,如果找到,则把相应的节点移到链表头部;如果没有找到,创建一个新的节点,插入到链表头部。链表尾部为“最久未被使用”的页面,即淘汰的目标。

​ LRU近似(老化算法aging):为每个页面设置一个移位寄存器,每隔一段时间,所有寄存器右移1位,并将访问位R值从左移入,淘汰寄存器中数值最小的页面。

5.3.4 最不频繁使用(LFU算法)

​ 把最不常用的页面先淘汰。具体实现:每一页可设立一个计算器,每访问一次后,将该页的计数器加1,然后淘汰计数值最小的页。

5.3.5 第二次机会算法(Second Chance算法)

​ 如果被淘汰的数据之前被访问过,则给其第二次机会实现。具体实现:每个页面会增加一个访问标志位,用于标识次数据装入内存后是否被再次访问过。若A是FIFO队列中最旧的页面,且其放入队列后没有被再次访问,则A被立刻淘汰;否则,如果放入队列后被访问过,则将A移到FIFO队列头,并且将访问标志位清除。如果所有页面都被访问过,则经过一次循环后,就按FIFO原则淘汰。

5.3.6 工作集算法

其实还是不太明白工作集算法,欢迎大佬讲解~

  • 工作集:进程运行正在使用的页面集合。
  • 工作集的动态变化
    • 进程开始执行后,随着不断访问新页面逐步建立较稳定的工作集。
    • 当内存访问的局部性区域的位置大致稳定时,工作集大小也大致稳定。
    • 局部性区域的位置改变时,工作集快速扩张收缩过渡到下一个稳定值。
  • 工作集算法
    • 给定一个进程,记录其工作集。
    • 当需要进行页面替换时,选择不在工作集中的页面进行替换。

5.3.7 时钟算法(Clock算法)

​ 时钟算法是Second Chance的改进。通过一个环形队列,避免数据在FIFO队列中移动。其命中率和Second Chance算法相同,复杂度和代价低于Second Chance算法。

  • 如果没有缺页错误,将所访问页的访问位置1,指针不动;
  • 如果产生缺页错误
    • (a)如果当前页面的访问位是1:首先将当前页面的访问位置0,将指针向前移一个位置;重复这个过程,直到找到访问位为0的页面,然后转(b)。
    • (b)如果当前页面的访问位是0:则替换当前页面,并将其访问问置为1,并将其指针向前移动一个位置。

在这里插入图片描述

5.4 缺页中断

​ 缺页中断的处理过程具体步骤如下:

  1. 现场保护:陷入内核态,保存必要的信息(OS及用户进程状态相关的信息)。
  2. 页面定位:查找出发生缺页中断的虚拟页面(进程地址空间中的页面)。这个虚拟页面的信息通常会保存在一个硬件寄存器中,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析该指令,通过分析找出发生页面中断的虚拟页面。
  3. 权限检查:检查虚拟地址的有效性及安全保护型。如果发生保护错误,则杀死该进程。
  4. 新页面调入(1):查找一个空闲的页框(物理内存中的页面),如果没有空闲页框则需要通过页面置换算法找到一个需要换出的页框。
  5. 旧页面写回:如果找的页框中的内容被修改了,则需要将修改的内容保存到磁盘上(此时需要将页框值为忙状态,以防页框被其他进程抢占掉)。
  6. 新页面调入(2):页框“干净”后,操作系统将保持在磁盘上的页面内容复制到该页框中。
  7. 更新页表:当磁盘中的页面内容全部装入页框后,向CPU发送一个中断。操作系统更新内存中的页表项,将虚拟页面映射的页框号更新为写入的页框,并将页框标记为正常状态。
  8. 恢复现场:恢复缺页中断发生前的状态,将程序指针重新指向引起缺页中断的指令。
  9. 继续执行:程序重新执行引发缺页中断的指令,进行存储访问。

在这里插入图片描述

6. 其他内容

6.1 内存抖动

6.2 写时复制技术

6.3 内存映射文件

6.4 存储保护

以上部分内容引自课件和《操作系统使用教程(第三版)》,如有侵权,请及时联系我删除!

猜你喜欢

转载自blog.csdn.net/NickHan_cs/article/details/106550044