存储管理机

Tags: , ,

1.存储管理机

在单任务计算机系统里,主存被划分为两块:一块装操作系统(内核),一块装应用程序。系统主存被单一的应用进程独占,没有存储管理的需求。但在多任务计算机系统上,装应用程序的那块主存则必须进一步划分数块,一块装一个应用程序。操作系统负责动态划分主存,分配主存给应用程序和回收应用程序释放的主存,这个任务叫存储管理(memory management)。负责管理存储器的操作系统子系统,我们称之存储管理子系统,统称[存储管理机]。

[存储管理机]的管理效率关系到整个多任务系统的性能。例如,如果系统主存只能装少量几个应用程序,而当主存中全是需频繁读写慢速IO设备的应用程序时,CPU频繁被闲置的同时,可能有其它就绪的应用程序因为没有被装入主存而被闲置,CPU资源没有被得到高效利用。

2.存储管理需求

无论计划设计或正在设计一项产品,我们务必时刻紧记产品所满足的需求(requirements),根据需求来考虑更好的设计策略。现代多任务计算机系统应用对操作系统的[存储管理机]设计提出以下一些需求:

  1. 进程移动(Relocation)
  2. 进程隔离保护(Protection)
  3. 数据共享(Sharing)
  4. 进程模块化(Logical organization)
  5. 虚拟存储

这些需求深深的影响着从硬件(CPU)到软件(OS、compiler suit)的体系结构设计。

2.1 进程移动

在多任务计算机里,多个进程共享系统可用的主存。通常情况下,程序员在开发程序的时候不可能对程序实际运行在主存时的情况作任何假设,例如程序被具体装入到主存哪里,主存其它位置有什么进程等;

另外,为了最大化CPU的利用率,系统需要利用辅存(主要是磁盘)开辟一块的进程池(pool of ready processes),将阻塞的进程调出主存,将就绪的进程调入主存。当进程被调出主存后,我们很难知道它何时被再次调入,因为它必须被调入回原来的主存位置。然而这种静态置换是低效的。

综合以上两个需求,我们需要某种移动进程(或者叫重定位relocation)的技术,可以将进程移动到主存任意位置。这让我的关注点转移到进程对象运行时的存储结构上来,如下图:

此图展示了一支进程的存储结构。为了简化描述,我们假设进程被装入一块连续的主存区。由存储结构可知,操作系统必须知道进程地址有:

  • 第一,进程控制块的地址;
  • 第二,进程调用栈的地址;
  • 第三,进程的程序入口地址。

由于操作系统是负责将进程装入主存的,因此这些进程地址很容易得到。进程除了以上的结构性地址,程序内部的指令序列还有很多内存引用地址。例如,分支指令(语句)包含了下一条指令的地址;数据引用指令包含了数据字节(或字)的地址。

由上可推得,为了满足进程地址重定位的最直观方案就是,以进程为单位移动,进程内统一使用某种逻辑地址(例如相对地址),逻辑地址在执行时再由CPU硬件和操作系统转为物理地址。

2.2 虚拟存储

以进程为单位移动和管理存储,所得效率还是有限的。如果能将移动的单位深入到进程内部,将不常用的部分暂时移出主存,存储管理效率将会更高。这就向存储管理提出更高级的管理需求——进程内部存储管理。

在多任务技术发展的初期,程序员们曾经开发一种【前内存管理系统】——覆盖系统(overlay system)来实现内部存储管理的问题。因为那个时候操作系统还没有出现,程序员通过显式编码来实现overlay system。程序员把程序划分为不同的段(sections),每个段都会被整个载入主存执行一段时间。随着程序的运行推进,新的程序段会被载入,替换已经不需要的程序段。

内部存储管理的任务原是程序开发者的职责,但出于以下两个原因,管理任务还是收归给系统:

  • 第一,开发者对程序的行为是了解的,但是存储管理毕竟不是解题相关的任务,由开发者实现存储管理,第一,分裂的开发者的角色,第二,增加了开发者的劳动;
  • 第二,某些程序动态性过强,开发者不容易预测。

现代计算机系统统统实现了虚拟存储技术来满足进程内部存储管理需求。虚拟存储技术的核心是[虚拟存储器]的概念。虚拟存储器不是主存,也不是外存,而是操作系统和CPU利用二者实现的抽象的存储器,它的功能与主存一样,但是比主存要慢。虚拟存储技术假想将进程载入虚拟存器上运行,主存是虚拟存器的缓存,进程的常用代码和数据缓存在主存上。

要为进程虚构一个虚拟存储器,并且以主存为缓存,那么存储管理机必须负责管理缓存的[命中]和[不命中]处理,前者就是分页技术中用页表来实现虚实地址转换,后者就是分页技术中缺页处理。

2.3 进程隔离保护

在多任务的环境,每支进程都必须彼此隔离独立。为了避免进程间产生有意或无意相互干扰——某一进程在没有得到允许的情况下读写其它进程所分配的主存空间,操作系统有责任窃查进程行为。由于进程行为都表现对主存的访问,因此进程行为的检查归为存储管理,而不是进程管理。

从某种意义上说,[进程移动]与[进程保护]是对立的,进程重定位实现增加了进程保护的难度。由于[进程重定位],进程在主存中的位置变得不可预知,不可能在编译时检查绝对地址来实现保护。此外,很多高级语言支持在运行时动态计算来获得数据对象的地址,例如,C语言,增加了进程保护的难度。

进程保护的可行办法是对进程运行时产生的所有地址进行检查,确保它们只访问属于自己的地址空间。可是,操作系统无法对进程的主存引用操作作全面的检查,光有操作系统(软件)是不够的,储存管理要实现[进程保护],必须得到CPU(硬件)支持。

幸运的是,现代处理器实现了强大的地址硬件,[进程移动]与[进程保护]同时得到实现。

2.4 数据共享

如果进程的隔离保护设计足够灵活,那么进程保护可以现实满足更高级的存储管理需求——数据共享。

在多任务的环境下,多个进程共享数据的例子有:第一,同一程序的多个进程实例可共享一份只读的代码;第二,两支协作进程可共享一份数据来实现通信协作;第三,基于同一个代码库,如标准C库,编写的多个进程可共享一份库代码,大大节省存储空间。

2.5 进程模块化

无论从概念上还是物理实现上,计算机主存都是线性的,无结构的。但是程序是有一定结构的,如一般程序有只读的代码段和可读写的数据段;进程运行时有一部分代码是常用的,有些则很少使用等。如果存储管理能以程序模块为位进行管理,而是不整个程序,那么以下的一些需求将得到满足:

  • 第一,程序模块可是单独编写和编译,并且可以在运行时动态链接和加载;
  • 第二,进程保护可以以模块为单位;
  • 第三,进程共享可以以模块为单位。

3.存储管理机设计

3.1 主存框

存储管理机管理的[资源]是主存,存储管理设计的第一任务是划分主存作管理的单位(memory allocation unit),这里统称其为主存框(memory frame);其次就是管理操作——为装入主存运行的进程分配主存区的分配算法。

划分主存的方式决定了存储管理机的类型,各种类型的优点与缺点都不同,适用于不的计算机应用系统。固定实存分配不适于通用PC,但非常适合用于嵌入式单机系统,因为它调度算法简单高效。

3.2 分配算法

将进程装入主存,装入分两种情况,第一,当主存有剩余[主存框]时,选择合适的[主存框]直接装入(Placement);第二,当主存没有剩余[主存框]时,必须先解决将哪个[主存框]调出主存,再装入(Replacement)。

4.存储管理机分类

根据实现[进程移动]时的地址翻译的难度,存储管理机分为[一次翻译的实存管理]和[二次翻译的虚存管理]两大类。在大类内又可根据[主存框]的类型进一步细分。

根据进程分配粒度,实存管理分为静态和动态实存; 静态实存管理按进程为单位进行分配和调度,并且主存框的划分是固定的(起始地址固定);根据主存框的[大小是否相等],静态实存管理机有[固定块式实存管理机]和[不定块实存管理机]两个变种。

动态实存主要有页式实存管理机和段式实存管理机两类。页框是大小固定的,段框则大小不一。

实存管理现在已经很少使用,由于它的实现比较原始,更好展示存储管理原理,对理解虚存管理有帮助;

虚存管理为了实现更灵活的存储管理,需要二次地址翻译——一张中间数据表提供翻译信息,例如页表。虚存管理设计的[主存框]类型主要有页和段,相应的存储管理机分别称为[页式虚存管理机]和[段式虚存管理机]。

  • 实存管理机
    • 静态实存管理机
      • 固定块式实存管理机
      • 不定块式实存管理机
    • 动态实存管理机
      • 页式实存管理机
      • 段式实存管理机
  • 虚存管理机
    • 页式虚存管理机
    • 段式虚存管理机

5.实存管理机

[固定块式实存管理机]优点是,第一,因为[主存框]大小和位置都是固定的,所以Placement算法很简单;第二,主存容纳进程的数量是固定的,Replacement算法也比较简单;缺点是,如果进程太大(超过[主存框]大小)则必须手动管理——程序中有部分代码用来管理内存(如将部分代码或者调入调出),增加USER开发者劳动;如果太小,产生[内部碎片]——主存框没有装满,但也不能再被利用;[不定块式实存管理机]缓解(但不能解决)这两个不足。

[动态实存管理机]很好的解决了手动管理和内部碎片,但会产生[外部碎片]——主存没有装满,但剩余空间因不足再装一个新进程而不能再被利用。外部碎片必须重新回收——移动主存上的进程来合并碎片——才能再用,直接的结果,第一,增加系统开销;第二,增加开发技术难度(增加OS开发者劳动),因为进程必须能重定位才能移动。

由于[动态实存管理机]的[主存框]大小是不固定的,Placement算法相对复杂,因为如果有多块可用的[主存框]时,必须先决定装入哪块[主存框],常用的选择算法有Best-fit 、First-fit 和Next-fit。

实存管理机基本实现了进程移动、进程保护和进程模块化的存储管理需求。例如,80×86体系CPU实现的段寻址技术,操作系统在载入进程时,将其基地址配置入CPU的基地址寄存器(base register),CPU通过基地址寄存器和相对地址来产生物理地址。CPU提供的边界寄存器(bounds register)可用来实现对进程的越界保护,当产生的物理地址越出指定范围,CPU产生一中断事件给操作系统处理。

6.页式虚存管理机

实存管理技术(无论是静态还是动态的)对主存的利用率不高,原因是[一次地址翻译]使主存框的分配方式不够灵活,只能连续的分配。试想如果进程的主存框能灵活地分配在不连续的主存框上,主存的利用率一定能得到改善。但这种管理方案的基础和前提是实现分割进程的技术。这就是目前被普遍实现的[页式虚拟存储技术]。

页式虚拟存储技术的思想是将进程分割为大小相等的页(page),主存分割为同样大小的页框(page frame),操作系统和CPU负责管理管理实现页与页框的映射关系。分页技术使用更小的主存框,降低了内部碎片的浪费;另外,分页技术支持不连续分配页框,也降低了外部碎片的浪费。

6.1 地址翻译原理

为了实现页式虚拟存储技术的[进程分割]和[不连续分配页框],程序的[逻辑地址]使用单一的[基地址寄存器加相对地址]进行一次转换的是不够的,存储管理机必须为每一支进程创建一张页表(page table)对程序的[逻辑地址]作二次转换。存储管理机将可用主存分割为同样大小页框,进程的页表保存着它所占用的页框的页框号。而页表的索引就是进程分割的页号(由0开始)。例如某进程D被分为五页,分别载入员框号为4,5, 6, 11和 12的页框内,如下图:

程序内的[相对地址]在分为两部分:页号和页内偏移。进程的物理地址通过用页号查得页框号,再由页框号和页内偏移合并得到。例如,假设系统使用16位地址,页大小为1K。那么一支2700字节大小的进程占用三页,如下图。当程序有相对地址的1502,那么如何算进程对应的物理地址呢?

1502的二进制是0000010111011110,由于页大小为1K,所以低10位用作页内偏移,高6位用作页号。那么相对地址1502位于1号页 (000001)内的478 (0111011110) 处。如果程序载入时1号页被分配到6号页框(000110),那相对地址的1502的对应的物理地址是0001100111011110,如下图。

分页技术最巧妙的地方是,当页大小为2的乘幂(2^n)时,页号和页内偏移对程序员、编译程序和链接程序是透明的。另外,地址转换过程只是将高位页号替换为页框号,硬件可非常容易并且高效实现。

6.2 多级页表

原理上,一支进程对应一张页表,但当某支进程所使用的虚地址范围很大的时候,它的页表将大得难以接受。例如,在VAX architecture的系统里,每支进程占用 2^31 = 2 Gib的虚地址范围,按每页2^9 = 512-byte大小算,页表项高达2^22 条。为了解决这个问题,大多数虚存管理使用虚存本身——多级页表——来保存页表,而不是使用物理内存。当然[顶级页表]必须使用物理内存。使用虚存来保存页表意味着进程的部分页表可以不在物理内存上。

一些处理器使用两级页表,像Pentium processor。在这种设计里,[顶级页表]称为页目录(page directory),一条目录项指向一张二级页表;这样如果页目录长度为X,页表最大长度为Y,那么每支进程可占用 X * Y 页。另外,页表最大长度取决于页大小,例如页大小为4Kib,那么如果页项为4byte,页表最大长度为1024。

下图(上部)展示了典型的使用二级页表划分32位地址空间的例子。假设我们是按字节寻址,页大小为4Kib,那么4-Gib (2^32) 虚拟地址空间由2^20页组成。如果页项(page table entry or PTE)大小为4byte,那么页表占用 4 Mib (2^22)的主存空间。这张庞大的页表(称为尾页表)本身就可被另一张页表(称为根页表)使用2^10页进一步映入虚存中。

上图(下部)展示了使用两级页表进行地址转换步骤。其中,进程的根页表是始终保存在主存上的,并由CPU根页表指针指向(具体如X86的cr3寄存器);虚拟地址前10位是一级页号,用以索引根页表,查得保存尾页表的页框(的基地址)。如果该页不在主存中,产生缺页事件;如果在,虚拟地址接着的10位用作二级页号,用以索引尾页表,查得最终的页框(的基地址),最后将页框的基地址和12位的偏移地址合并得到物理地址。

刘建文原创,引用请注明出处。

Leave a comment