第三章:内存管理
知识框架

3.1 内存管理概念
3.1.1 内存管理的概念
概念
内存管理 (MemoryManagement)是操作系统设计中最重要和最复杂的内容之一。操作系统对内存的划分和动态分配,就是内存管理的概念。
内存管理的功能
内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。
地址转换:在多道程序环境下, 程序中的逻辑地址与内存中的物理地址不可能一致, 因此存储管理必须提供地址变换功能,把逻辑地址转换成相应的物理地址。
内存空间的扩充:利用虚拟存储技术或自动覆盖技术,从逻辑上扩充内存 。
存储保护:保证各道作业在各自的存储空间内运行,互不干扰。
进程运行的基本原理和要求
-
程序装入和链接
- 创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序 ,通常需要以下几个步骤:
- 编译:由编译程序将用户源代码编译成若干个目标模块。
- 链接: 由链接程序将编译后形成的一组目标模块,以及所需库函数链接在一起,形成一个完整的装入模块。
- 装入:由装入程序将装入模块装入内存运行。
- 程序的链接有以下三种方式:
- 态链接:在程序运行之前,先将各目标模块及它们所需的库函数链接成一个完整的可执行程序,以后不再拆开。
- 装入时动态链接:将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。
- 运行时动态链接:对某些目标模块的链接,是在程序执行中需要该目标模块时,才对它进行的链接。
- 创建进程首先要将程序和数据装入内存。将用户源程序变为可在内存中执行的程序 ,通常需要以下几个步骤:

-
内存的装入模块在装入内存时,同样有以下三种方式 :
-
绝对装入:绝对装入程序按照装入模块中的地址,将程序和数据装入内存。由于程序中的逻辑地址与实际内存地址完全相同,故不需对程序和数据的地址进行修改。绝对装入方式只适用于单道程序环境。
-
可重定位装入:在多道程序环境下,多个目标模块的起始地址通常都是从0开始,程序中的其他地址都是相对于起始地址的,此时应采用可重定位装入方式。
静态重定位的特点是在一个作业装入内存时,必须分配其要求的全部内存空间,如果没有足够的内存,就不能装入该作业。
-
动态运行时装入:也称为动态重定位, 程序在内存中如果发生移动,就需要采用动态的装入方式。这种方式需要一个重定位寄存器的支持。
动态重定位的特点:
- 可以将程序分配到不连续的存储区中;
- 在程序运行之前可以只装入它的部分代码即可投入运行,然后在程序运行期间,根据需要动态申请分配内存;
- 便于程序段的共享,可以向用户提供一个比存储空间大得多的地址空间。
-
-
逻辑地址空间与物理地址空间
- 相对地址 (或逻辑地址 ):编译后,每个目标模块都是从0号单元开始编址,称为该目标模块的相对地址 (或逻辑地址 )。
- 逻辑地址空间:当链接程序将各个模块链接成 一个完整的可执行目标程序时,链接程序顺序依次按各个模块的相对地址构成统 一的从0号单元开始编址的逻辑地址空间。
- 物理地址空间:是指内存中物理单元的集合,它是地址转换的最终地址,进程在运行时执行指令和访问数据最后都要通过物理地址从主存中存取。
- 地址重定位:当装入程序将可执行代码装入内存时,通过地址转换将逻辑地址转换成物理地址的过程。
-
内存保护
- 内存分配前,需要保护操作系统不受用户进程的影响,同时保护用户进程不受其他用户进程的影响。
- 内存保护可采取两种方法:
- 在 CPU 中设置一对上、下限寄存器,存放用户作业在主存中的下限和上限地址,每当CPU要访问 一个地址时,分别和两个寄存器的值相比,判断有无越界。
- 通过采用重定位寄存器 (或基址寄存器)和界地址寄存器 (又称限长寄存器)来实现这种保护。
- 重定位寄存器和界地址寄存器:
- 重定位寄存器是用来“加”的,逻辑地址加上重定位寄存器中的值就能得到物理地址;
- 界地址寄存器是用来“比”的, 通过比较界地址寄存器中的值与重定位寄存器加上逻辑地址的值来判断是否越界。
3.1.2 覆盖与交换
覆盖与交换技术是在多道程序环境下用来扩充内存的两种方法。
覆盖
覆盖的基本思想
由于程序运行时并非任何时候都要访问程序及数据的各个部分(尤其是大程序),因此可以把用户空间分成一个固定区和若干个覆盖区。
将经常活跃的部分放在固定区, 其余部分按调用关系分段。首先将那些即将要访问的段放入覆盖区,其他段放在外存中,在需要调用前,系统再将其调入覆盖区,替换覆盖区中原有的段。
覆盖技术的特点
打破了必须将一个进程的全部信息装入主存后才能运行的限制,但当同时运行程序的代码量大于主存时仍不能运行。
内存中能够更新的地方只有覆盖区的段,不在覆盖区中的段会常驻内存。
交换
交换(对换)的基本思想
把处于等待状态(或在CPU调度原则下被剥夺运行权利)的程序从内存移到辅存,把内存空间腾出来,这一过程又叫换出;把准备好竞争 CPU 运行的程序从辅存移到内存,这一过程又称为换入。
交换需要注意问题
- 交换需要备份存储,通常是快速磁盘。它必须足够大,并且提供对这些内存映像的直接访问。
- 为了有效使用CPU,需要每个进程的执行时间比交换时间长,而影响交换时间的主要是转移时间。转移时间与所交换的内存空间成正比。
- 如果换出进程,必须确保该进程是完全处于空闲状态。
- 交换空间通常作为磁盘的一整块,且独立于文件系统,因此使用就可能很快。
- 交换通常在有许多进程运行且内存空间吃紧时开始启动,而系统负荷降低就暂停。
- 普通的交换使用不多,但交换策略的某些变种在许多系统中(如 UNIX 系统)仍发挥作用 。
覆盖&交换联系
-
交换技术主要是在不同进程(或作业)之间进行,而覆盖则用于同一个程序或进程中。
-
由于覆盖技术要求给出程序段之间的覆盖结构,使得其对用户和程序员不透明,所以对于主存无法存放用户程序的矛盾,现代操作系统是通过虚拟内存技术来解决的,覆盖技术则己成为历史;而交换技术在现代操作系统中仍具有较强的生命力。
3.1.3 连续分配管理方式
概述
连续分配方式,是指为一个用户程序分配一个连续的内存空间,比如说某用户需要1GB的内存空间,它就在内存空间中分配一块连续的 1GB的空间给用户。
它主要包括单一连续分配、 固定分区分配和动态分区分配。
单一连续分配
概述
内存在此方式下分为系统区和用户区,系统区仅提供给操作系统使用,通常在低地址部分;用户区是为用户提供的、除系统区之外的内存空间。 这种方式无需进行内存保护。
特点
优点:简单、无外部碎片,可以采用覆盖技术,不需要额外的技术支持。
缺点:只能用于单用户、单任务的操作系统中,有内部碎片,存储器的利用率极低。
固定分区分配
概述
固定分区分配是最简单的一种多道程序存储管理方式,它将用户内存空间划分为若干个固定大小的区域,每个分区只装入一道作业。
当有空闲分区时,便可以再从外存的后备作业队列中, 选择适当大小的作业装入该分区,如此循环。
固定分区分配的两种方法:
-
分区大小相等:用于利用一台计算机去控制多个相同对象的场合, 缺乏灵活性。
-
分区大小不等:划分为含有多个较小的分区、适量的中等分区及少量的大分区。

为便于内存分配,通常将分区按大小排队, 并为之建立一张分区说明表,其中各表项包括每个分区的起始地址、大小及状态(是否己分自己)。 当有用户程序要装入时,便检索该表,以找到合适的分区给予分配并将其状态置为“己分配”;未找到合适分区则拒绝为该用户程序分配内存。

分区方式存在问题
- 程序可能太大而放不进任何一个分区中,这时用户不得不使用覆盖技术来使用内存空间;
- 主存利用率低, 当程序小于固定分区大小时,也占用了一个完整的内存分区空间,这样分区内部有空间浪费 ,这种现象称为内部碎片。
动态分区分配
概述
动态分区分配又称为可变分区分配,是一种动态划分内存的分区方法。这种分区方法不预先将内存划分,而是在进程装入内存时,根据进程的大小动态地建立分区 ,并使分区的大小正好适合进程的需要。因此系统中分区的大小和数目是可变的。

外部碎片:在所有分区外的存储空间会变成越来越多的碎片,与固定分区中的内部碎片正好相对。
紧凑 (Compaction)技术:操作系统不时地对进程进行移动和整理,需要动态重定位寄存器的支持,且相对费时。
分配策略算法
首次适应 (First Fit) 算法:空闲分区以地址递增的次序链接。分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。
-
最佳适应 ( Best Fit )算法:空闲分区按容量递增形成分区链,找到第一个能满足要求的空闲分区。
-
最坏适应 ( Worst Fit )算法:又称最大适应 ( Largest Fit )算法,空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。
-
邻近适应 ( Next Fit )算法:又称循环首次适应算法,由首次适应算法演变而成。不同之处是分配内存时从上次查找结束的位置开始继续查找。
在这几种方法中,首次适应算法不仅是最简单的,而且通常也是最好和最快的。

3.1.4 非连续分配管理方式
概述
非连续分配允许一个程序分散地装入到不相邻的内存分区中。如果采用非连续分配管理方式,作业所要求的1GB内存空间可以分散地分配 在内存的各个区域,当然,这也需要额外的空间去存储它们(分散区域)的索引,使得非连续分配方式的存储密度低于连续存储方式。
非连续分配管理方式根据分区的大小是否固定分为分页存储管理方式和分段存储管理方式。
分页存储管理方式
概述
分页存储管理方式中,根据运行作业时是否要把作业的所有页面都装入内存才能运行分为基本分页存储管理方式和请求分页存储管理方式。
基本分页存储管理方式
分页思想:把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位。每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间。
分页的方法从形式上看,像分区相等的固定分区技术,分页管理不会产生外部碎片。
**每个进程平均只产生半个块大小的内部碎片(也称页内碎片) **。
-
页面和页面大小
- 页(Page):进程中的块。
- 页框(Page Frame):内存中的块。
- 块( Block):外存中的块。
-
地址结构
- 前一部分为页号 P,后一部分为页内偏移量 W。
- 地址长度为 32 位, 其中0-11位为页内地址,即每页大小为4KB;12-31位为页号,地址空间最多允许有220页。

-
页表
- 概念:为了便于在内存中找到进程的每个页面所对应的物理块,系统为每个进程建立一张页表,记录页面在内存中对应的物理块号,页表一般存放在内存中;
- 页表项与地址都是由两部分构成,而且第-部分都是页号,但页表项的第二部分是物理内存中的块号,而地址的第二部分是页内偏移,页表项的第二部分与地址的第二部分共同组成物理地址。
- 页表的作用是实现从页号到物理块号的地址映射。

基本地址变换机构
地址变换机构的任务是将逻辑地址转换为内存中物理地址,地址变换是借助于页表实现的。
在系统中通常设置一个页表寄存器(PTR),存放页表在内存的始址F和页表长度M。

假设页面大小为L,逻辑地址A到物理地址E的变换过程如下(逻辑地址、页号、 每页的长度都是十进制数):
-
计算页号P ( P = A / L P=A/L P=A/L) 和页内偏移量 W ( W = A ( m o d L ) W=A\pmod L W=A(modL))。
-
比较页号P和页表长度M,若 P ≤ M P\leq M P≤M,则产生越界中断,否则继续执行。
-
页表中页号P对应的页表项地址=页表起始地址 F+页号 P*页表项长度,取出该页表项内容b,即为物理块号。
-
计算 E = b ∗ L + W E=b*L+W E=b∗L+W,用得到的物理地址E去访问内存。
页式管理中地址空间是一维的。
具有快表的地址变换机构
问题:若页表全部放在内存中,则存取一个数据或一条指令至少要访问两次内存:第一次是访问页表,第 二 次才根据该地址存取数据或指令,这种方法比通常执行指令的速度慢了一半。
优化:地址变换机构中增设了一个具有并行查找能力的高速缓冲存储器一快表(与此对应,主存中的页表也常称为慢表),又称联惜想寄存器 (TLB),用来存放当前访问的若干页表项,以加速地址变换的过程。

快表分页机制地址变换过程:
-
CPU给出逻辑地址后,由硬件进行地址转换并将页号送入高速缓存寄存器,并将此页号 与快表中的所有页号进行比较。
-
果找到匹配的页号,说明所要访问的页表项在快表中 , 则直接从中取出该页对应的页框号,与页内偏移量拼接形成物理地址。
-
如果没有找到,则需要访问主存中的页表,在读出页表项后 ,应同时将其存入快表,以便后面可能的再次访问。
但若快表己满,则必须按照一定的算法对旧的页表项进行替换。
作用:一般快表的命中率可以达到则以上,这样,分页带来的速度损失就降低到附以下。 快表的有效性是基于著名的局部性原理。
两级页表
二级页表实际上就是在原有页表结构上再加了一层页表

作用:建立多级页表的目的在于建立索引,这样不用浪费主存空间去存储无用的页表项,也不用盲目地顺序式查找页表项。
基本分段存储管理方式
背景
分页管理方式是从计算机的角度考虑设计的,以提高内存的利用率,提升计算机的性能,且分页通过硬件机制实现,对用户完全透明;而分段管理方式的提出则是考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要。
分段
段式管理方式按照用户进程中的自然段划分逻辑空间。逻辑地址由段号 S 与段内偏移量 W 两部分组成。( 连续地址空间:段内要求连续, 段间不要求连续 ,因此整个作业的地址空间是二维的)

在页式系统中,逻辑地址的页号和页内偏移量对用户是透明的,但在段式系统中,段号和段内偏移量必须由用户显示提供,在高级程序设计语言中,这个工作由编译程序完成。
段表
每个进程都有一张逻辑空间与内存空间映射的段表,其中每一个段表项对应进程的一个段,段表项记录该段在内存中的起始地址和段的长度。

在配置了段表后,执行中的进程可通过查找段表,找到每个段所对应的内存区。 可见, 段表用于实现从逻辑段到物理内存区的映射。

地址变换机构
为了实现进程从逻辑地址到物理地址的变换功能,在系统中设置了段表寄存器,用于存放段表始址F和段表长度M。

从逻辑地址A到物理地址E之间的地址变换过程:
- 从逻辑地址A中取出前几位为段号S,后几位为段内偏移量W;
- 比较段号S和段表长度M, 若 S ≥ M S\geq M S≥M ,则产生越界中断,否则继续执行;
- 表中段号 S对应的段表项地址=段表起始地址 F+段号 S×段表项长度,取出该段表项的前几位得到段长C。若段内偏移量 ≥ C \geq C ≥C,则产生越界中断,否则继续执行;
- 取出段表项中该段的起始地址 b,计算 E = b + W E=b+W E=b+W,用得到的物理地址E去访问内存。
段的共享与保护
-
在分段系统中,段的共享是通过两个作业的段表中相应表项指向被共享的段的同一个物理副本来实现的。
-
当一个作业正从共享段中读取数据时,必须防止另一个作业修改此共享段中的数据。不能修改的代码称为纯代码或可重入代码(它不属于临界资源),这样的代码和不能修改的数据是可以共享的,而可修改的代码和数据则不能共享。
-
与分页管理类似,分段管理的保护方法主要有两种:① 存取控制保护,② 地址越界保护。
-
分段管理的地址空间是二维的。
段页式管理方式
概述
页式存储管理能有效地提高内存利用率 ,而分段存储管理能反映程序的逻辑结构井有利于段的共享。如果将这两种存储管理方法结合起来,就形成了段页式存储管理方式。
在段页式系统中,作业的地址空间首先被分成若干个逻辑段, 每段都有自己的段号,然后再将每一段分成若干个大小固定的页。对内存空间的管理仍然和分页存储管理一样,将其分成若干个和页面大小相同的存储块,对内存的分配以存储块为单位。

在段页式系统中,作业的逻辑地址分为三部分:段号、页号和页内偏移量。

注意:在一个进程中,段表只有一个,而页表可能有多个。
在进行地址变换时,首先通过段表查到页表起始地址,然后通过页表找到页帧号,最后形成物理地址。段页式管理的地址空间是二维的。

3.2 虚拟内存管理
3.2.1 虚拟内存的基本概念
传统存储管理方式的特征
- 一次性
- 作业必须一次性全部装入内存后,方能开始运行。
- 问题:
- 当作业很大,不能全部被装入内存时,将使该作业无法运行;
- 当大量作业要求运行时,由于内存不足以容纳所有作业,只能使少数作业先运行,导致多道程序度的下降。
- 驻留性
- 作业被装入内存后,就一直驻留在内存中,其任何部分都不会被换出,直至作业运行结束。
- 问题:运行中的进程 , 会因等待I/O而被阻塞 ,可能处于长期等待状态。
局部性原理
局部性原理表现在以下两个方面:
- 时间局部性:
- 如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。
- 时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,井使用高速缓存的层次结构实现。
- 空间局部性:
- 一旦程序访问了某个存储单元,在不久之后 ,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也 一般是以向量、数组、表等形式簇聚存储的。
- 空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。
虚拟内存技术实际上就是建立了“内存一外存”的两级存储器的结构,利用局部性原理实现高速缓存。
虚拟存储器的定义和特征
定义:在程序装入和执行过程中,操作系统提供了部分装入、请求调入和置换功能(将程序所需要的部分调入内存,将暂时不使用的内容换出到外存上 ),好像为用户提供了一个比实际内存大得多但实际上并不存在的存储器,称为虚拟存储器。
主要特征:
- 多次性:是指无需在作业运行时一次性地全部装入内存,而是允许被分成多次调入内存运行。
- 对换性:是指无需在作业运行时一直常驻内存,而是允许在作业的运行过程中,进行换进和换出。
- 虚拟性:是指从逻辑上扩充内存的容量,使用户所看到的内存容量,远大于实际的内存容量。
虚拟内存技术的实现
虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。
虚拟内存实现方式:
- 请求分页存储管理
- 请求分段存储管理
- 请求段页式存储管理
虚拟内存硬件支持:
-
一 定容量的内存和外存。
-
页表机制(或段表机制),作为主要的数据结构。
-
中断机构,当用户程序要访问的部分尚未调入内存,则产生中断。
-
地址变换机构,逻辑地址到物理地址的变换。
3.2.2 请求分页管理方式
概述
请求分页系统建立在基本分页系统基础之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。
在请求分页系统中,只要求将当前需要的一部分页面装入内存,便可以启动作业运行。在作业执行过程中,当所要访问的页面不在内存时,再通过调页功能将其调入,同时还可以通过置换功能将暂时不用的页面换出到外存上,以便腾出内存空间。
页表机制
请求分页系统在请求页表项中增加了以下四个宇段:

- 状态位 P:用于指示该页是否己调入内存,供程序访问时参考。
- 访问字段 A:用于记录本页在一段时间内被访问的次数,或记录本页最近己有多长时间未被访问,供置换算法换出页面时参考。
- 修改位 M:标识该页在调入内存后是否被修改过。
- 外存地址:用于指出该页在外存上的地址,通常是物理块号,供调入该页时参考。
缺页中断机构
- 在请求分页系统中,每当所要访问的页面不在内存时,便产生一个缺页中断,请求操作系统将所缺的页调入内存;
- 此时应将缺页的进程阻塞〈调页完成唤醒),如果内存中有空闲块,则分配一个块,将要调入的页装入该块,并修改页表中相应页表项;
- 若此时内存中没有空闲块,则要淘汰某页(若被淘汰页在内存期间被修改过,则要将其写回外存)。
缺页中断与一般的中断区别:
-
在指令执行期间产生和处理中断信号 ,而非一条指令执行完后,属于内部中断。
-
一条指令在执行期间,可能产生多次缺页中断。
地址变换机构
请求分页系统中的地址变换机构,是在分页系统地址变换机构的基础上,为实现虚拟内存,又增加了某些功能而形成的。

地址变换过程:
- 若找到要访问的页,便修改页表项中的访问位(写指令则还须重置修改位),然后利用页表项中给出的物理块号和页内地址形成物理地址。
- 若未找到该页的页表项,应到内存中去查找页表,再对比页表项中的状态位P,看该页是否己调入内存,未调入则产生缺页中断,请求从外存把该页调入内存。
3.2.3 页面置换算法
概念
进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区。而选择调出页面的算法就称为页面置换算法。(决定应该换入哪页换出哪页)
好的页面置换算法应有较低的页面更换频率, 也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出。
常见置换算法
最佳置换算法 (OPT)
概述
最佳 (Optimal, OPT) 置换算法所选择的被淘汰页面将是以后永不使用的,或者是在最长时间内不再被访问的页面,这样可以保证获得最低的缺页率。
但由于人们目前无法预知进程在内存下的若干页面中哪个是未来最长时间内不再被访问的, 因而该算法无法实现。
最佳置换算法可以用来评价其他算法。
先进先出( FIFO)页面置换算法
概述
优先淘汰最早进入内存的页面,亦即在内存中驻留时间最久的页面。该算法实现简单 , 只需 把调入内存的页面根据先后次序链接成队列,设置一个指针总指向最早的页面。
FIFO算法还会产生当所分配的物理块数增大而页故障数不减反增的异常现象,这是由 Belady 于 1969 年发现 , 故称为 Belady 异常。只有 FIFO 算法可能出现 Belady 异常, 而 LRU 和 OPT 算法永远不会出现 Belady 异常。
最近最久未使用( LRU)直换算法
概述
选择最近最长时间未访问过的页面予以淘汰,它认为过去一段时间内未访问过的页面,在最近的将来可能也不会被访问。
该算法为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
LRU 性能较好,但需要寄存器和栈的硬件支持。LRU 是堆栈类的算法。理论上可以证明, 堆栈类算法不可能出现 Belady 异常。FIFO 算法基于队列实现 ,不是堆栈类算法。
时钟(CLOCK)置换算法
概述
因为算法要循环扫描缓冲区检查各页面的情况,像时钟的针一样转动,所以叫CLOCK算法,又称为最近未用(Not Recently Used, NRU)算法。
CLOCK 算法的性能比较接近LRU,而通过增加使用的位数目,可以使得 CLOCK 算法更加高效。在使用位的基础上再增加一个修改位,则得到改进型的CLOCK置换算法。
算法执行操作步骤
- 从指针的当前位置开始,扫描帧缓冲区。在这次扫描过程中,对使用位不做任何修改。 选择遇到的第一个帧( u=0, m=0)用于替换。
- 如果第1步失败,则重新扫描,查找( u=0, m=1)的帧。选择遇到的第一个这样的帧到用于替换。在这个扫描过程中,对每个跳过的帧,把它的使用位设置成0。
- 如果第2步失败,指针将回到它的最初位置,并且集合中所有帧的使用位均为0。 重复第1步,并且如果有必要,重复第2步。这样将可以找到供替换的帧。
改进型的 CLOCK 算法优于简单 CLOCK 算法之处,在于替换时首选没有变化的页。由于修改过的页在被替换之前必须写回,因而这样做会节省时间。
3.2.4 页面分配策略
驻留集大小
现代操作系统通常采用三种策略:
- 固定分配局部置换
- 说明:它为每个进程分配一定数目的物理块 ,在整个运行期间都不改变。
- 缺点:太少会频繁出现缺页中断,太多又会使CPU和其他资源利用率下降。
- 可变分配全局置换
- 说明:为系统中的每个进程分内配一定数目的物理块,操作系统自身也保持一个空闲物理块队列。当某进程发生缺页时,系统从空闲物理块队列中取出一个物理块分配给该进程,井将欲调入的页装入其中。
- 优点:比固定分配局部置换更加灵活,可以动态增加进程的物理块。
- 缺点:盲目地给进程增加物理块,将会导致系统多道程序并发能力下降。
- 可变分配局部置换
- 说明:它为每个进程分配一定数目的物理块,当某进程发生缺页时,只允许从该进程在内存的页面中选出一页换出,如果进程在运行中频繁地缺页,系统再为该进程分配若干物理块,直至该进程缺页率趋于适当程度;反之,若进程在运行中缺页率特别低,则可适当减少分配给该进程的物理块。
- 优点:不仅可以动态增加进程物理块的数量,还能动态减少进程物理块的数量,在保证进程不会过多地调页的同时,也保持了系统的多道程序并发能力。
- 缺点:需要更复杂的实现,也需要更大的开销。
调入页面的时机
为确定系统将进程运行时所缺的页面调入内存的时机,可采取以下两种调页策略:
- 预调页策略
- 以预测为基础的预调页策略,将预计在不久之后便会被访问的页面预先调入内存。
- 这种策略主要用于进程的首次调入时,由程序员指出应该先调入哪些页。
- 请求调页策略
- 进程在运行中需要访问的页面不在内存而提出请求,由系统将所需页面调入内存。
- 由于这种策略调入的页一定会被访问,且这种策略比较易于实现,故在目前的虚拟存储器中大多采用此策略。
- 缺点:每次只调入一页,调入调出页面数多时会花费过多的I/O开销。
预调入实际上就是运行前的调入,请求调页实际上就是运行期间调入。一般情况下 ,两种调页策略会同时使用。
从何处调入页面
请求分页系统中的外存分为两部分:用于存放文件的文件区和用于存放对换页面的对换区。
对换区通常是采用连续分配方式,而文件区采用离散分配方式,故对换区的磁盘 I/O 速度比文件区的更快。
从何处调入页面有三种情况:
- 系统拥有足够的对换区空间
- 可以全部从对换区调入所需页面,以提高调页速度。
- 在进程运行前,需将与该进程有关的文件从文件区复制到对换区。
- 系统缺少足够的对换区空间
- 凡不会被修改的文件都直接从文件区调入。
- 当换出这些页面时 , 由于它们未被修改而不必再将它们换出。
- 对于那些可能被修改的部分,在将它们换出时须调到对换区, 以后需要时再从对换区调入(这是因为读的速度比写的速度快)。
- UNIX 方式
- 与进程有关的文件都放在文件区,故未运行过的页面,都应从文件区调入。
- 曾经运行过但又被换出的页面,由于是被放在对换区,因此下次调入时应从对换区调入。
- 进程请求的共享页面若被其他进程调入内存,则无需再从对换区调入。
3.2.5 抖动
概述
在页面置换过程中的一种最糟糕的情形是,刚刚换出的页面马上又要换入主存 ,刚刚换入的页面马上就要换出主存,这种频繁的页面调度行为称为抖动 ,或颠簸。
如果一个进程在换页上用的时间多于执行时间 , 那么这个进程就在颠簸。
原因
频繁的发生缺页中断(抖动),其主要原因是某个进程频繁访问的页面数目高于可用的物理页帧数目。
3.2.6 工作集
概念
**工作集 (或驻留集)**是指在某段时间间隔内,进程要访问的页面集合。经常被使用的页面需要在工作集中,而长期不被使用的页面要从工作集中被丢弃。
为了防止系统出现抖动现象,需要选择合适的工作集大小。
原理
-
让操作系统跟踪每个进程的工作集,并为进程分配大于其工作集的物理块。
-
如果还有空闲物理块,则可以再调一个进程到内存以增加多道程序数。
-
如果所有工作集之和增加以至于超过了可用物理块的总数, 那么操作系统会暂停一个进程,将其页面调出并且将其物理块分配给其他进程,防止出现抖动现象。
正确选择工作集的大小,对存储器的利用率和系统吞吐量的提高 ,都将产生重要影响。
3.2.7 小结
为什么要引入虚拟内存
在物理上扩展内存相对有限的条件下,以一些其他可行的方式在逻辑上来扩充内存。
虚拟内存空间的大小决定因素
虚拟存储器的大小由计算机的地址结构决定,并非是内存和外存的简单相加。
虚存的大小要同时满足 2 个条件:
- 虚存的大小 < 内存容量和外存容量之和
- 这是硬件的硬性条件规定的, 若虚存大小超过了这个容量则没有相应的空间来供虚存使用。
- 虚存的大小 < 计算机的地址位数能容纳的最大容量
- 按字节编址,一个地址代表1B的存储空间,则32位地址只能访问大小<4GB(2的32 次方B)缓存地址;
实际虚存的容量是取条件1、2的交集,也就是说,两个条件都要满足,光满足一个是不行的。
虚拟内存优缺点
优点:虚拟内存使用了外存上的空间来扩充内存的空间,通过一定的换入换出,使得整个系统在逻辑上能够使用一个远远超出其物理内存大小的内存容量。
缺点:虚拟内存技术调换页面时需要访问外存,会导致平均访存时间下降,如果使用了不合适的替换算法,则会大大降低系统性能。
3.3 本章疑难点
分页管理方式和分段管理方式对比

本章知识架构图
