文章目录

  • 第四章 存储器管理
    • 4.1 存储器的层次结构
      • 4.1.1 多层结构的存储器系统
      • 4.1.2 主存储器与寄存器
      • 4.1.3 高速缓存和磁盘缓存
    • 4.2 程序的装入和链接
      • 4.2.1 地址以及映射
      • 4.2.2 程序的装入
      • 4.2.3 程序的链接
    • 4.3 连续分配存储管理方式
      • 4.3.1 单一连续分配
      • 4.3.2 固定分区分配
      • 4.3.3 动态分区分配
      • 4.3.4 基于顺序搜索的动态分区分配算法
      • 4.3.5 基于索引搜索的动态分区分配算法
      • 4.3.6 动态可重定位分区分配
      • 4.3.7 分区的保护
    • 4.4 对换
      • 4.4.1 引入
      • 4.4.2 原理
      • 4.4.3 优缺点
      • 4.4.4 需要考虑的问题
    • 4.5 分页存储管理方式
      • 4.5.1 分页存储管理的基本方法
      • 4.5.2 地址变换机构
      • 4.5.3 访问内存的有效时间(EAT)
      • 4.5.4 两级页表
      • 4.5.5 反置页表
    • 4.6 分段存储管理方式
      • 4.6.1 分段存储管理方式的引入
      • 4.6.2 分段系统的基本原理
      • 4.6.3 分页和分段的区别
      • 4.6.4 段页式存储管理方式

第四章 存储器管理

4.1 存储器的层次结构

​ 计算机执行时,几乎每条指令都涉及对存储器的访问,因此要求对存储器的访问速度跟得上处理机的运行速度。考虑到价格和现实因素,如今的计算机大都采用了多层结构的存储器系统。

4.1.1 多层结构的存储器系统

​ 在上述系统中,从上往下依次:

  • 访问速度越慢
  • 空间容量越大
  • 单位价格越低

​ 其中,CPU 寄存器和主存又被称为可执行存储器,其中的信息在掉电后不复存在。但是辅存中的信息可以长期保存。

​ 对于可执行存储器和辅存,计算机访问的机制是不同的。程序需要从辅存中载入可执行存储器才可以执行,访问辅存的时间远大于访问可执行存储器的时间。

4.1.2 主存储器与寄存器

(1)主存储器

​ 简称内存或主存,用于保存进程运行时的程序和数据。

​ 通常,处理机都是从主存储器中取得指令和数据的,并将其所取得的指令放入指令寄存器中,而将其所读取的数据装入到数据寄存器中;或者反之,将寄存器中的数据存入到主存储器。

​ 主存的访问速度虽然也很快,但是还不够匹配 CPU 执行指令的速度,因此在计算机系统中引入了寄存器和高速缓冲存储器(Cache)。

(2)寄存器

​ 寄存器具有与处理机相同的速度,故对寄存器的访问速度最快,完全能与 CPU 协调工作,但价格却十分昂贵,因此容量不可能做得很大。

​ 一般寄存器的数量较少,早期一台计算机只有几个或十几个寄存器。目前,通用计算机中大多为数十个到上百个。

4.1.3 高速缓存和磁盘缓存

(1)高速缓存

​ 高速缓冲存储器介于寄存器和存储器之间,主要用于备份主存中常用的数据,以减少处理机对主存储器的访问次数,大幅提高程序执行速度。

​ 高速缓存的容量远大于寄存器,目前通常为数 MB。

​ 在 Win10 系统中可以通过任务管理器的性能栏查看高速缓存。

​ 高速缓存通常分为多级结构,从高级到低级依次:

  • 访问速度降低
  • 容量增加

(2)磁盘缓存

​ 为了缓和磁盘与主存的访问速度差异,设置了磁盘缓存,用于暂时存放频繁使用的一部分磁盘数据和信息,减少访问磁盘的次数。

​ 与高速缓存不同,它并不实际存在,而是利用主存中的部分存储空间暂时存放磁盘中的信息。因此主存也可以看成是辅存的“高速缓存”。

4.2 程序的装入和链接

​ 用户源程序在系统中运行,必须先将其装入内存,然后转变为一个可执行程序。通常需要以下几个步骤:

  1. 编译。

    由编译器(Compiler)对用户源程序进行编译,形成若干个目标模块(Object Module)。

  2. 链接。

    由链接程序(Linker)将目标模块以及其所需要的目标函数链接在一起,形成一个完整的装入模块(Load Module)。

  3. 装入。

    由装入程序(Loader)将装入模块装入内存。

4.2.1 地址以及映射

(1)逻辑地址 / 相对地址 / 虚地址

​ 用户程序经过汇编或编译后形成目标代码,目标代码通常采用相对地址的形式。

  • 首地址记为 0,其余指令的地址都相对于首地址来进行编址,称为相对地址。
  • 相对地址的集合称为相对地址空间,也简称地址空间
  • 不能使用逻辑地址在内存中读取信息。

(2)物理地址 / 绝对地址 / 实地址

  • 内存中存储单元的实际地址,可以直接寻址。

  • 内存单元的集合称为存储空间绝对地址空间

(3)地址映射 / 重定位

​ 将用户程序中的逻辑地址转换为运行时由机器直接寻址的物理地址。

​ 当程序装入内存时, 操作系统要为该程序分配一个合适的内存空间,由于程序的逻辑地址与分配到内存物理地址不一致, 而 CPU 执行指令时,是按物理地址进行的,所以要进行地址转换。

4.2.2 程序的装入

(1)绝对装入方式

​ 如果计算机系统很小,仅能运行单道程序,完全可以事先知道程序将存入内存的什么位置。此时编译过程中可以直接产生绝对地址的目标代码,不需要对程序和数据的地址进行修改。

  • 优点:装入过程简单
  • 缺点:不适用于多道程序系统

(2)可重定位装入方式

​ 在多道程序的环境下,编译程序不可能预知目标模块放入内存的地址,因此编译后形成的若干个目标模块的起始地址通常都是 0。装入程序会将模块中的相对地址与程序在内存中的起始地址相加,得到程序的物理地址再装入程序。

​ 这种方法通常在装入程序后便不再对程序的地址进行修改,因此也称为静态重定位方式。

​ 上图中程序在内存中的起始地址为 10000。除了应修改数据地址外,指令地址也须做同样的修改.

  • 优点:不需要硬件的支持,可以装入有限多道程序。
  • 缺点:不允许程序运行时在内存中移动位置。

(3)动态运行时的装入方式

​ 上述方法虽可以应用于多道程序环境,将装入模块装入到内存中的任何允许的位置,但不允许程序在运行时移动位置。因此,我们通常需要采用动态运行时装入的方式。

​ 动态运行时的装入程序在把装入模块装入内存后,并不立即把装入模块中的逻辑地址转换为物理地址,而是把这种地址转换推迟到程序真正要执行时才进行。因此,装入内存后的所有地址都仍是逻辑地址。为使地址转换不影响指令的执行速度,这种方式需要一个重定位寄存器的支持。

  • 优点:允许运行中的进程在内存中移动。
  • 缺点:需要硬件支持。
4.2.3 程序的链接

​ 源程序经过编译后,可得到一组目标模块。链接程序将这组目标模块以及它们所需要的库函数装配成一个完整的装入模块,并且将个目标模块中的相对地址和外部调用符号转换成装入模块中的相对地址。

​ 根据链接时间的不同,可以把链接分为以下三种:

(1)静态链接方式

​ 在程序运行之前,先将各目标模块以及它们所需的库函数链接成一个完整的装配模块,以后便不再拆开。

​ 采用这种方式时,需要解决以下两个问题:

  1. 对相对地址进行修改(图 a)
  2. 变换外部调用符号(图 b)

(2)装入时动态链接

​ 链接在装入时进行,即在装入一个目标时,若发生一个外部模块的调用事件,则由装入程序去找出相应的外部模块,将它装入内存,并把它链接到调用者模块上(按照上面的方式)。

​ 在装入或运行时进行链接。通常被链接的共享代码称为动态链接库(DLL,Dynamic-Link Library)或共享库(shared library)。

  • 优点:

    • 便于修改和更新
    • 便于实现对目标模块的共享

(3)运行时动态链接

​ 链接在运行时进行,即在执行过程中,当发现一个被调用模块还没装入内存时,立即由 OS 找出该模块,将它装入内存,并把它链接到调用者模块上。

​ 在执行过程中未被用到的目标模块,都不会被调入内存和链接。

  • 优点:加快程序的装入过程,节省内存空间

4.3 连续分配存储管理方式

4.3.1 单一连续分配

​ 在早期的单道程序环境下,存储器管理将内存分为两个部分:

  • 系统区

    仅提供给 OS 使用,通常放在内存的低址部分。

  • 内存区

    系统区以外的全部内存空间, 提供给用户使用。仅装有一道用户程序。

4.3.2 固定分区分配

​ 将用户空间划分为若干个固定大小的区域,在每个分区中只装入一道作业。这样使得能在内存中装入多道程序,并且程序之间互不干扰,可以并发运行。

(1)划分分区的方法

  1. 分区大小相等

    缺点:缺乏灵活性

    • 程序太小时,会造成空间浪费
    • 程序太大时,无法装入程序

    尽管如此,对于利用一台计算机同时控制多个相同对象的场合,仍然被广泛采用。因为这些对象内存空间大小往往相同。

  2. 分区大小不等

    通常把内存区划分成:

    • 多个小分区
    • 适量的中等分区
    • 少量的大分区

    这样就可以根据程序的大小分配适合的区域,增加了存储器分配的灵活性。

(2)内存分配

​ 为了方便内存分配,通常将分区按期大小进行排队,并为之建立一张分区使用表,如图所示。

4.3.3 动态分区分配

​ 也称为可变分区分配,根据进程的实际需要,动态地为之分配内存空间。其实现主要包括以下三个方面:

(1)数据结构

​ 常用的数据结构主要有以下两种:

  • 空闲分区表
  • 空闲分区链(通常做法)

(2)分区分配算法

​ 在下面两个小节中详细介绍。

(3)分区分配操作

​ 主要操作是分配内存和回收内存。

  1. 分配内存

    设请求的分区大小为 u.size,表中每个空闲分区的大小可表示为 m.size。

    • 若 m.size-u.size ≤ size(size 是事先规定的不再切割的剩余分区的大小),说明多余部分太小,可不再切割,将整个分区分配给请求者。
    • 否则(即多余部分超过 size),便从该分区中按请求的大小划分出一块内存空间分配出去,余下的部分仍留在空闲分区链(表)中。然后,将分配区的首址返回给调用者。

  1. 回收内存

    根据回收区的首地址,从空闲区链中找到相应的插入点,根据回收部分尽可能大的原则,对下列四种情况分别作出不同操作:

    • 回收区与插入点的前一个空闲分区 F1 邻接。此时将二者合并,修改 F1 的大小,不为回收区分配新表项
    • 回收区与插入点的后一个空闲分区 F2 邻接。此时将二者合并,使用回收区的首地址作为新空闲区的首地址,大小为二者之和
    • 回收区同时与插入点的前、后两个分区 F1、F2 邻接。此时将三者合并,使用 F1 的首地址,大小为三者之和
    • 回收区前后没有空闲分区。此时为回收区单独建立一个新表项,填写回收区的首地址和大小,插入空闲链中。

4.3.4 基于顺序搜索的动态分区分配算法

​ 为了实现动态分区分配,通常是将系统中的空闲分区链接成一个链。所谓顺序搜索,是指依次搜索空闲分区链上的空闲分区,去寻找一个其大小能满足要求的分区。

​ 这种方法比较适用于不太大的系统。

(1)首次适应算法(first fit,FF)

​ 要求空闲分区链以地址递增的次序连接。

​ 每次从链首开始顺序查找,直到找到一个大小满足要求的空闲分区,将其分配给进程。

  • 优点:保留了高址部分的大空闲区,大作业可以得到分配
  • 缺点:低址部分不断被分配,留下许多难以被利用的。很小的空闲分区(碎片)

(2)循环首次适应算法(next fit,NF)

​ 要求将空闲区链形成一个环形链。

​ 类似上述顺序查找方式,但不是每次从链首开始查找,而是从上一次查找的空闲分区后面开始查找。

  • 优点:减少了查找空闲分区时的开销
  • 缺点:使内存中的空闲分区分布均匀,缺乏大的空闲分区,大作业难以被分配

(3)最佳适应算法(best fit,BF)

​ 要求将所有的空闲分区按照容量从小到大的顺序依次排列。

​ 每次为作业分配内存时,总是把能满足要求的最小空闲分区分配给它,避免大材小用。

  • 缺点:留下许多难以利用的碎片

(4)最坏适应算法(worst fit,WF)

​ 要求将所有的空闲分区按照容量从大到小的顺序依次排列。

​ 与 BF 恰好相反,每次挑选一个最大的空闲区,从中分割一部分分配给作业使用。

  • 优点:

    • 剩下空闲区不会太小,对中、小作业有利
    • 产生碎片的可能性最小
    • 查找效率很高,只要看第一个分区是否能满足即可
  • 缺点:缺乏大的空闲分区
4.3.5 基于索引搜索的动态分区分配算法

​ 为了提高搜索空闲分区的速度,在大、中型系统中往往会采用此类算法。

(1)快速适应算法(quick fit)

​ 也称为分类搜索算法。该算法将空闲分区根据容量大小进行分类,对每一类相同容量的所有空闲分区单独设立空闲分区链表,同时内存中设立一章管理索引表,记录每一种空闲分区的链表头指针,来管理各种不同类型的空闲分区。

​ 空闲分区的分类根据进程常用空间大小划分,例如 2KB、4KB、8KB。对于 7KB 的空闲区,可以放在 8KB 中,也可以放在一个特殊的空闲区链表中。

​ 搜索空闲区的步骤:

  1. 先从索引表中寻找能容纳进程的最小空闲区链表
  2. 从该链表中取下第一块进行分配,不对空闲区进行分割
  • 优点:

    • 能保留大的分区
    • 不产生内存碎片
    • 查找效率高
  • 缺点:
    • 为了有效合并分区,需要的算法较为复杂,系统开销大
    • 一个分区只属于一个进程,会有一定的空间浪费
  • 特点:典型的时间换空间的做法

(2)伙伴系统(buddy system)

​ 该算法规定,空闲分区只能为 2 的 k 次幂(k 为整数),通常,整个可分配内存的大小也是 2 的整数次幂。

​ 在系统运行过程中,会不断地划分空闲分区,按照大小进行分类,对相同大小的所有空闲分区单独设立一个空闲分区双向链表。因此共有 k 个空闲分区链表。

​ 分配过程:

  1. 首先找到一个满足条件的最小的 i,使得 2i-1 < n ≤ 2i(n 为进程所需空间大小)
  2. 查找空闲分区大小为 2i 的链表,若找到,则直接分配
  3. 若未找到,则查找空闲分区大小为 2i+1 的链表,若找到,则将其分为两个大小相等的连续空间,其中一个用于分配,另一个加入空闲分区大小为 2i 的链表中。这一对空闲分区称为“伙伴”
  4. 若未找到,则查找空闲分区大小为 2i+2 的链表,若找到,则将其分为两个大小相等的连续空间,其中一个用于分配,另一个加入空闲分区大小为 2i+1 的链表中。再将用于分配的一个空闲分区继续划分,其中一个用于分配,另一个加入空闲分区大小为 2i 的链表中
  5. 以此类推…
  6. 最坏情况下,可能需要对 2k 的空闲分区进行 k 次分割才能得到所需分区

​ 回收过程:

  1. 回收大小为 2i 的空闲分区时,若已存在其伙伴,则合并为大小为 2i+1 的空闲分区
  2. 若新空闲分区的伙伴已存在,则再次合并为大小为 2i+2 的空闲分区
  3. 以此类推…
  4. 合并时,伙伴一定是相邻的,因此合并后得到的新空闲分区一定是连续的

​ 对于一个大小为 2k,地址为 x 的内存块,其伙伴块的地址为:
buddyk(x)={x+2k,xmod2k+1=0x−2k,xmod2k+1=2kbuddy_{k}(x)= \left\{ \begin{array}{l} x+2^{k},& x\ mod\ 2^{k+1}=0\\ x-2^{k},& x\ mod\ 2^{k+1}=2^{k} \end{array} \right. buddyk​(x)={x+2k,x−2k,​x mod 2k+1=0x mod 2k+1=2k​

  • 优点:

    • 减少 小的空闲分区,提高了空闲分区的可使用率
  • 缺点:
    • 分配和回收时间较长,时间性能比快速适应法差,但比顺序搜索算法好

在多处理机系统中,此方法仍被广泛使用,但不是当前的主流

(3)哈希算法

​ 利用哈希快速查找的优点,以及空闲分区在可利用空闲区表中的分布规律,建立哈希函数,构造一张一空闲分区大小为关键字的哈希表,该表的每一个表项记录了一个对应的空闲分区链表。

​ 分配时,根据所需空闲分区大小,通过哈希函数计算,即得到在哈希表中的位置,从而得到相应的空闲分区链表

  • 优点:

    • 没有内碎片
  • 缺点:
    • 存在外碎片
    • 如果大小不是任意的,也可能出现内碎片
4.3.6 动态可重定位分区分配

(1)紧凑

​ 为了解决“外部碎片”的问题,将内存中的所有作业进行移动,从而将分散的多个空闲分区移到同一端拼接成一个大的空闲分区。这种技术称为“拼接”或“紧凑”。

  • 缺点:

    • 在每次“紧凑”后,都必须对移动了的程序或数据进行重定位,大大影响系统的效率。

​ 下面的动态重定位方法将能很好地解决此问题。

(2)动态重定位

​ 在之前介绍的动态运行时装入的方式中,作业装入内存后的所有地址仍然都是相对(逻辑)地址。而将相对地址转换为绝对(物理)地址的工作被推迟到程序指令要真正执行时进行。为使地址的转换不会影响到指令的执行速度,必须有硬件地址变换机构的支持,即须在系统中增设一个重定位寄存器,用它来存放程序(数据)在内存中的起始地址。程序在执行时,真正访问的内存地址是相对地址与重定位寄存器中的地址相加而形成的。

​ 在此方式中,地址的变换过程是在程序执行期间,随着对每条指令或数据的访问自动进行的,故称为动态重定位。当系统对内存进行了“紧凑”,而使若干程序从内存的某处移至另一处时,不需对程序做任何修改,只要用该程序在内存的新起始地址去置换原来的起始地址即可(但是程序还是需要移动的)。

(3)动态重定位分区分配算法

​ 动态重定位分区分配算法与动态分区分配算法基本上相同,差别仅在于:在这种分配算法中,增加了紧凑的功能。

4.3.7 分区的保护

​ 在连续分配方式中,为了防止一个用户作业破坏 OS 或其他用户的作业,常采用界限寄存器或保护键的方法来进行分区的保护。

(1)界限寄存器

​ 可以是一对上、下限寄存器,也可以是一对基址、限长寄存器。

​ 每当进行内存访问时,硬件自动将所访问的内存地址与界限寄存器的值进行比较,若发生地址越界,则产生越界中断。

(2)保护键

​ 它为每个分区分配一个独立的保护键,相当于一个锁;同时为每个进程分配一个相应的钥匙。保护键可设置成对读写同时保护的或只对读、写进行单项保护的。

​ 当进行内存访问时,都要检查钥匙和被访问单元的锁是否匹配,若不匹配,则发生保护性中断

4.4 对换

​ 也称为交换技术。最早用于麻省理工学院的单用户分时系统 CTSS 中。由于当时计算机的内存都非常小,为了使该系统能分时运行多个用户程序而引入了对换技术。系统把所有的用户作业存放在磁盘上,每次只能调入一个作业进入内存,当该作业的一个时间片用完时,将它调至外存的后备队列上等待,再从后备队列上将另一个作业调入内存。这就是最早出现的分时系统中所用的对换技术。现在已经很少使用。

​ 要实现内、外存之间的对换,系统中必须有一台 I/O 速度较高的外存,而且其容量也必须足够大,能容纳正在分时运行的所有用户作业,目前最常使用的是大容量磁盘存储器。

4.4.1 引入

​ 多个程序并发执行,可以将暂时不能执行的程序送到外存中,从而获得空闲内存空间来装入新程序,或读入保存在外存中而目前到达就绪状态的进程。交换单位可以为整个进程的地址空间(进程对换),也可以为进程的部分地址空间(页面对换/分段对换)。

​ 程序暂时不能执行的可能原因

  • 处于阻塞状态
  • 低优先级(确保高优先级程序执行)
4.4.2 原理
  • 换出:暂停执行内存中的进程,将整个进程的地址空间保存到外存的交换区中
  • 换入:将外存中由阻塞变为就绪的进程的地址空间读入到内存中,并将该进程送到就绪队列
4.4.3 优缺点
  • 优点:

    • 增加并发运行的程序数目
    • 给用户提供适当的响应时间
    • 编写程序时不影响程序结构
  • 缺点:

    • 对换入和换出的控制增加处理机开销

    • 程序整个地址空间都进行传送,没有考虑执行过程中地址访问的统计特

4.4.4 需要考虑的问题
  1. 程序换入时的重定位
  2. 减少交换中传送的信息量,特别是对大程序对外存交换区空间的管理:如动态分区方法

4.5 分页存储管理方式

​ 非连续分配允许一个程序分散地装入不相邻的内行分区。

​ 在连续分配管理方式中,我们发现,即使内存若超过 1GB 的空闲空间,但若没有连续的 1GB 空间,则需要 1GB 空间的作业仍然是无法运行的;但若采用非连续分配管理方式,则作业所要求的 1GB 内存空间可以分散地分配在内存的各个区域,当然,这也需要额外的空间去存储它们(分散区域)的索引,使得非连续分配方式的存储密度低于连续存储方式的。

​ 非连续分配管理方式根据分区的大小是否固定,分为分页存储管理方式分段存储管理方式

​ 我们把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位。每个进程也以块为单位划分,进程在执行时,以块为单位逐个申请主存中的块空间。这样,进程只会在最后一个不完整的块申请一个主存块空间时,才会产生主存碎片,这种碎片相对于进程来说是很小的,称为页内碎片。

4.5.1 分页存储管理的基本方法

(1)页面和物理块

​ 进程中的块称为“页”;内存中的块称为“页框”;外存直接称为“块”。三者都以相同的单位进行划分。

​ 进程在执行时需要申请主存空间,为每个页面分配主存中的可用页框,即进程中的页需要和主存中的页框一一对应:
页号块号02132638⋮⋮\begin{array}{| c | c |} \hline \text{页号} & \text{块号}\\ \hline 0 & 2\\ 1 & 3\\ 2 & 6\\ 3 & 8\\ \vdots & \vdots\\ \hline \end{array} 页号0123⋮​块号2368⋮​​
​ 为了方便地址转换,页面大小应该为 2 的整数幂。页面的大小应该适当选择:

  • 过大:页内碎片增大
  • 过小:页表增长,内存占用大

(2)地址结构

​ 分页地址中的地址结构为:

​ 其中 0 ~ 11 位为页内地址,表示每页的大小为 4KB;12 ~ 31 位为页号,表示地址空间最多允许有 1M 页。

​ 给定一个地址 A,若页面大小为 L,则页号 P 和页内地址 d 可以通过以下公式求出:
P=INT[AL],d=[A]MODLP=INT\Big[{A\over L}\Big],\qquad d=[A]\ MOD\ L P=INT[LA​],d=[A] MOD L
(3)页表

​ 为了保证进程能够在内存中找到每个页面对应的物理块,需要为每个进程建立一张页面映像表,简称页表:

​ 页表项的第二部分(块号 P)与地址的第二部分(页内偏移量 W)共同组成物理地址:
addr=P∗L+Waddr=P*L+W addr=P∗L+W

4.5.2 地址变换机构

​ 地址变换机构的任务是将逻辑地址中的页号转换为内存中的物理块号,借助于页表来完成。

(1)基本的地址变换机构

​ 因为每条指令的地址都需要进行变换,因此需要采用硬件来实现。

​ 在系统中只设置一组页表寄存器 PTR(Page-Table Register),存放页表在内存的起始地址 F 和页表长度 M。平时进程未执行时,页表的起始地址和长度存放在其 PCB 中,当其裕兴时,将其装入 PTR 中。

​ 当进程需要访问逻辑地址 A 中的数据时:

  1. 计算页号 P=A/LP=A /LP=A/L 和页内偏移量 W=A%LW=A\%LW=A%L

  2. 比较页号 PPP 和页表长度 MMM,若 P≥MP\ge MP≥M,则产生越界错误

  3. 找出页号 PPP 对应的块号 bbb,类似于寻找数组元素的地址,(P,b)(P,\ b)(P, b) 表项对应的地址计算公式为:
    addr(P,b)=F+P∗kaddr_{(P, b)}=F+P*k addr(P,b)​=F+P∗k
    其中,kkk 为页表项长度,即页地址占用的内存空间。

  4. 计算
    addr=b∗L+Waddr = b*L+W addr=b∗L+W
    得到地址访问内存。

​ 采用这种方法,每条指令将访问 2 次内存:

  1. 访问页表,计算得到物理地址
  2. 访问物理地址得到值

​ 这样会使计算机处理速度降低一半。

(2)基于快表的地址变换机构

​ 在地址变换机构中增设一个具有并行查找能力的高速缓冲存储器(Cache)——快表,也称相联存储器 / 联想寄存器(TLB),用来存放档期啊访问的若干表项。主存中的页表也相应地称为“慢表”。

​ 于是,地址变换过程变为如下:

  1. 计算 PPP 和 WWW 并检查 PPP 的长度

  2. 将 PPP 送入 TLB 中,进行查找

    • 若找到匹配的页号,直接取出对应的页框号,计算物理地址

    • 若未找到,访问主存中的慢表,计算物理地址

      同时将该页表项存入 TLB 中,方便后续查找

      若 TLB 已满,则需要一定的替换策略选出其中一项进行替换

有些处理机令快表和慢表同时查找,当在快表中查找成功,则终止慢表的查找

​ 快表由于成本问题,一般不会做的很大,通常只存放 16 ~ 512 个页表项。一般快表的命中率可达 90% 以上,这样分页带来的速度损失就可以降低到 10% 以下。

4.5.3 访问内存的有效时间(EAT)

​ 内存的有效访问时间(Effective Access Time):从进程发出指定逻辑地址的访问请求,经过地址变换,到在内存中找到对应的实际物理地址单元并取出数据,所需要花费的总时间。

(1)基本的地址变换机构

​ 假设访问一次内存的时间为 t,于是:
EAT=t+t=2tEAT=t+t=2t EAT=t+t=2t

(2)基于快表的地址变换机构

​ 假设 λ\lambdaλ 为查找快表的时间,a 为命中率,则:
EAT=aλ+(t+λ)(1−a)=(2−a)t+λ\begin{aligned} EAT &=a\lambda+(t+\lambda)(1-a)\\ &=(2-a)t+\lambda \end{aligned} EAT​=aλ+(t+λ)(1−a)=(2−a)t+λ​

4.5.4 两级页表

​ 目前,大多数计算机系统都支持非常大的逻辑地址空间(232 ~ 264)。假设对于一个具有 32 位的逻辑地址空间的分页系统,页面大小若为 4KB,则每个进程中页表的页表项可以达到 1M 之多,并且要求内存连续,这显然是不合实际的。因此,我们还需要考虑页表本身的大小。

(1)离散分配页表(多级页表)

​ 我们可以将页表进行分页,使得每个页面的大小与内存物理块的大小相同,并为其编号,离散地将各个页面分别存放在不同的物理块中。因此,我们为页表再建立一张页表,称为外层页表,每个页表项中记录了页表页面的物理块号。

​ 例如,当使用一层页表时,一共有 220 个页表项。而建立二级页表时,每页中包含 210 个页表项,最多允许有 210 个页表分页:

(2)需要时调入

​ 上述方法只是将连续的大页表进行了划分 / 分割,但是不加其他处理的话,我们还需要在内存中存放 220 个页表项才能找到每一个逻辑地址对应的物理地址。因此,我们必须在需要该页表时再调入内存,这样才能减少内存的占用。

​ 详细情况在下一章——虚拟存储器中介绍。

4.5.5 反置页表

(1)引入原因

​ 在现代计算机系统中,通常允许一个进程的逻辑地址空间非常大,因此就需要有许多的页表项,而因此也会占用大量的内存空间。

​ 为了减少页表占用的内存空间,引入了反置页表。

​ 反置页表为每一个物理块设置一个页表项,并将它们按物理块的编号排序,其中的内容则是页号其所隶属进程的标识符

(2)地址变换

  1. 根据进程标识符和页号,检索反置页表
  2. 找到匹配的页表项时,其序号便是该页所在的物理块号(因为表项按物理块的编号排序),直接将其与页内地址进行计算得到物理地址
  3. 若检索不到匹配的页表项,说明此页尚未调入内存

​ 由于反置页表按照物理地址编号,而不是逻辑地址,因此可以大大减少内存的占用。

4.6 分段存储管理方式

​ 分页管理方式是从计算机的角度考虑设计的,目的是提高内存的利用率,提升计算机的性能。分页通过硬件机制实现,对用户完全透明。

​ 分段管理方式的提出则考虑了用户和程序员,以满足方便编程、信息保护和共享、动态增长及动态链接等多方面的需要。

4.6.1 分段存储管理方式的引入

​ 由于通常的程序都可分为若干个段,如主程序段、子程序段 A、子程序段 B、… 、数据段以及栈段等,每个段大多是一个相对独立的逻辑单位。

​ 另一方面,实现和满足信息共享、信息保护、动态链接以及信息的动态增长等需要,也都是以段为基本单位的。更具体地说,分段存储管理方式更符合用户和程序员多方面的需要:

(1)方便编程

​ 通常,用户把自己的作业按照逻辑关系划分为若干个段,每个段都从 0 开始编址,并有自己的名字和长度。因此,程序员们都迫切地需要访问的逻辑地址是由段名(段号)和段内偏移量(段内地址)决定的,这不仅可以方便程序员编程,也可使程序非常直观,更具可读性。

(2)信息共享

​ 在实现对程序和数据的共享时,是以信息的逻辑单位为基础的。分页系统中的“页”只是存放信息的物理单位(块),一个可被共享的过程往往可能需要占用数十个页面,这为实现共享增加了困难。

​ 我们可以为该被共享过程建立一个独立的段,这就极大地简化了共享的实现。

(3)信息保护

​ 信息保护同样是以信息的逻辑单位为基础的,而且经常是以一个过程、函数或文件为基本单位进行保护的。

​ 例如,我们希望函数 A 仅允许进程执行,而不允许读,更不允许写,那么,我们只须在包含了函数 A 的这个段上标上只执行标志即可。但是在分页系统中,函数 A 可能要占用若干个页面,而且其中的第一个和最后一个页面还会装有其它程序段的数据,它们可能有着不同的保护属性,如可以允许进程读写,这样就很难对这些页面实施统一的保护,因此,分段管理方式能更有效和方便地实现对信息的保护功能。

(4)动态增长

​ 在实际应用中,往往存在着一些段,尤其是数据段,在它们的使用过程中,由于数据量的不断增加,而使数据段动态增长,相应地它所需要的存储空间也会动态增加。对此,很难采取预先多分配的方法进行解决。前述的其它几种存储管理方式都难以应付这种动态增长的情况,而分段存储管理方式却能较好地解决这一问题。

(5)动态链接

​ 动态链接在作业运行之前,并不是把所有的目标程序段都链接起来。当程序要运行时,首先将主程序和它立即需要用到的目标程序装入内存,即启动运行。而在程序运行过程中,当需要调用某个目标程序时,才将该段(目标程序)调入内存并进行链接。可见,动态链接要求的是以目标程序(即段)作为链接的基本单位,因此,分段存储管理方式非常适合于动态链接。

4.6.2 分段系统的基本原理

(1)分段

​ 在分段存储管理方式中,作业的地址空间被划分为若干个段,每个段定义了一组逻辑信息。

​ 例如,有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等,每个段都有自己的名字。为了实现简单起见,通常可用一个段号来代替段名,每个段都从 0 开始编址,并采用段连续的地址空间。段的长度由相应的逻辑信息组的长度决定,因此各段的长度并不相等。

​ 整个作业的地址空间由于被分成多个段,所以呈现出二维特性,亦即,每个段既包含了部分地址空间,又标识了逻辑关系。其逻地址由段号(段名)和段内地址所组成。

​ 分段地址中的地址具有如下结构:

​ 在该地址结构中,允许一个作业最长有 64K 个段,每个段的最大长度为 64KB。

(2)段表

​ 为每个分段分配一个连续的分区。进程中的各个段,可以离散地装入内存中不同的分区中。

​ 类似于分页系统,需为每个进程建立一张段映射表,简称“段表”。每个段在表中占有一个表项,其中记录了该段在内存中的起始地址(基址)和段的长度。
段号 S段长 C本段在主存的起始地址 b\begin{array}{| c | c | c |} \hline \quad \text{段号 }S \quad & \quad \text{段长 }C \quad & \quad \text{本段在主存的起始地址 }b\quad \\ \hline \end{array} 段号 S​段长 C​本段在主存的起始地址 b​​
​ 段表可以存放在一组寄存器中,以利于提高地址转换速度。但更常见的方法是将段表放在内存中。在配置了段表后,执行中的进程可通过查找段表,找到每个段所对应的内存区。可见,段表用于实现从逻辑段到物理内存区的映射。

(3)地址变换机构

  1. 从逻辑地址 AAA 中取出段号 SSS,段内偏移量 WWW

  2. 比较 SSS 和 MMM 的长度,若 S≥MS\ge MS≥M,则产生越界错误

  3. 寻找段表中的段表项地址:
    addr(S,C,b)=F+S∗kaddr_{(S,\ C,\ b)}=F+S*k addr(S, C, b)​=F+S∗k
    其中,FFF 为段表的起始地址,kkk 为段表项长度。

    取出段长 CCC 后,与段内偏移量 WWW 比较,若 W≥CW\ge CW≥C,则产生越界错误

  4. 取出该段的起始地址 bbb,计算
    addr=b+Waddr=b+W addr=b+W
    得到地址后访问内存得到值。

​ 与页式管理不同,段式管理不能通过给出一个整数便确定对应的物理地址,因为每段的长度是不固定的,无法通过整数除法得出段号,元法通过求余得出段内偏移,所以段号和段内偏移一定要显式给出(S, W),因此分段管理的地址空间是二维的。

4.6.3 分页和分段的区别

(1)页是信息的物理单位,段则是信息的逻辑单位。

​ 采用分页存储管理方式是为实现离散分配方式,以消减内存的外零头,提高内存的利用率。或者说,分页仅仅只是系统管理上的需要,完全是系统的行为,对用户是不可见的。

​ 分段存储管理方式中的段则是信息的逻辑单位,它通常包含的是一组意义相对完整的信息。分段的目的主要在于能更好地满足用户的需要。

(2)页的大小固定且由系统决定,而段的长度却不固定。

​ 在采用分页存储管理方式的系统中,在硬件结构上,就把用户程序的逻辑地址划分为页号和页内地址两部分,也就是说是直接由硬件实现的,因而在每个系统中只能有一种大小的页面。

​ 而段的长度却不固定,决定于用户所编写的程序,通常由编译程序在对源程序进行编译时,根据信息的性质来划分。

(3)分页的用户程序地址空间是一维的,分段的用户程序的地址空间是二维的。

​ 分页完全是系统的行为,故在分页系统中,用户程序的地址是属于单一的线性地址空间,程序员只需利用一个记忆符即可表示一个地址。

​ 而分段是用户的行为,故在分段系统中,用户程序的地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

4.6.4 段页式存储管理方式

(1)基本原理

​ 在段页式系统中,作业的地址空间首先被分成若干逻辑段,每段都有自己的段号,然后将每段分成若干大小固定的页。对内存空间的管理仍然和分页存储管理一样,将其分成若干和页面大小相同的存储块,对内存的分配以存储块为单位。

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

(2)地址变换机构

​ 为了实现地址变换,系统为每个进程建立一张段表,每个分段有一张页表。段表表项中至少包括段号、页表长度和页表始址,页表表项中至少包括页号和块号。此外,系统中还应有一个段表寄存器,指出作业的段表始址和段表长度。

​ 在一个进程中,段表只有一个,页表可能有多个。

​ 段表寄存器和页表寄存器的作用都有两个:

  • 在段表或页表中寻址
  • 判断是否越界

​ 获得一条指令或数据,需要访问内存 3 次:

  1. 访问段表,获得页表起始地址
  2. 访问页表,获得该页所在的物理块号,与页内地址进行计算获得物理地址
  3. 访问物理地址,获得数据

​ 同样可以使用快表(TLB)加快查找速度:在地址变换机构中增设一个高速缓冲寄存器。每次访问它时,都须同时利用段号和页号去检索高速缓存,若找到匹配的表项,便可从中得到相应页的物理块号,用来与页内地址一起形成物理地址;若未找到匹配表项,则仍需第三次访问内存。基本原理与分页及分段的情况相似。

2021-11-04 《计算机操作系统》(第四版)学习笔记:第四章相关推荐

  1. 《鸟哥的私房菜基础篇》第四版学习笔记——第0章 计算机概论

    文章目录 http://linux.vbird.org/linux_basic/ 一.计算机:辅助人脑的好工具 1.计算机硬件的五大单元 2.一切设计的起点: CPU 的架构 3.其它单元的设备 4. ...

  2. 《鸟哥的私房菜基础篇》第四版学习笔记——第1章Linux是什么与如何学习

    文章目录 一.Liux是什么?? 1.是操作系统or应用程序?? 2.Linux之前,Unix的历史 3.关于 GNU 计划.自由软件与开放原始码 二.Torvalds 的 Linux 发展 1.与 ...

  3. JavaScript高级程序设计第四版学习--第二十四章

    title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...

  4. 《Real-Time Rendering》第四版学习笔记——Chapter 9 Physically Based Shading(二)

    上接文章:<Real-Time Rendering>第四版学习笔记--Chapter 9 Physically Based Shading(一) 六.微观几何 每个可见的表面点都包含了很多 ...

  5. 《Real-Time Rendering》第四版学习笔记——Chapter 9 Physically Based Shading(三)

    前文: <Real-Time Rendering>第四版学习笔记--Chapter 9 Physically Based Shading(一) <Real-Time Renderin ...

  6. 《Real-Time Rendering》第四版学习笔记——Chapter 9 Physically Based Shading(一)

    一.光的物理特性 光与物体的交互形成了基于物理着色的基础. 在物理层面上,光的模型为电磁横波.每个波都有一个单一的波长λ\lambdaλ.具有单一波长的光叫单色光(monochromatic ligh ...

  7. 视觉SLAM十四讲学习笔记-第四讲---第五讲学习笔记总结---李群和李代数、相机

    第四讲---第五讲学习笔记如下: 视觉SLAM十四讲学习笔记-第四讲-李群与李代数基础和定义.指数和对数映射_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第四讲-李代数求导与扰动模 ...

  8. 视觉SLAM十四讲学习笔记-第四讲-Sophus实践、相似变换群与李代数

    专栏系列文章如下: 视觉SLAM十四讲学习笔记-第一讲_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习笔记-第二讲-初识SLAM_goldqiu的博客-CSDN博客 视觉SLAM十四讲学习 ...

  9. PMBOK(第六版) 学习笔记 ——《第一章 引论》

    系列文章目录 PMBOK(第六版) 学习笔记 --<第一章 引论> PMBOK(第六版) 学习笔记 --<第二章 项目运行环境> PMBOK(第六版) 学习笔记 --<第 ...

  10. 数据库系统概论(第5版)学习笔记第1章 1.2——数据模型

    数据库系统概论(第5版)学习笔记第1章 1.2--数据模型 目录 数据库系统概论(第5版)学习笔记第1章 1.2--数据模型 0.思维导图(自制) 1️⃣思维导图下载 2️⃣图示 1.2数据模型 1. ...

最新文章

  1. *args and **kwargs in Python 变长参数
  2. mysql表jiayi_MySQL Memory存储引擎:优势及性能测试
  3. python创建虚拟环境venv_Python 3 使用venv创建虚拟环境
  4. 【TensorFlow】TensorFlow函数精讲之tf.clip_by_value()
  5. python初级第三库(人工智能,web解析,人机交互)
  6. Python字符串处理的8招秘籍
  7. 计算机管理格式化没有顺利完成,内存卡无法格式化
  8. “OneNMP”-超高性价比的实用网管工具
  9. TeamViewer远程控制
  10. 三种经典网页音乐播放器
  11. 如何在 Android 中减小 APK 大小?
  12. MapReduce计算PMI
  13. 案例|双循环下的国货自信:波司登抵御寒冬的新战袍
  14. ubuntu下使用Passenger配置redmine
  15. 海信A5无法进入系统,无法进入recovery,无法卡刷,无法进入edl,无法进入9008
  16. 【PSO三维路径规划】基于matlab粒子群算法融合鸡群算法多无人机三维路径规划【含Matlab源码 1792期】
  17. 实木餐桌四大保养方法,90%的人都不知道
  18. python爬取中国天气网中国全部城市的天气链接
  19. 数据库事务开启,提交与回滚
  20. 基于Solidworks的三维光路结构示意图绘制实例演示

热门文章

  1. 253云通讯 php curl请求 json格式不对
  2. Python : 深度学习DIGITS
  3. VS2015+QT运行C# dll,出现“错误C2182 “t”: 非法使用“void”类型”的解决方案
  4. 【Java】学习日记 Day11
  5. [Java] 代理模式 Proxy Mode
  6. Linux网络管理实战1
  7. 基于8255A接口芯片的跑马灯程序
  8. 9月20日重磅发布:中国云计算创新企业50强|榜单征集
  9. 人体存在感应雷达应用,飞睿科技雷达传感器,雷达感应模块技术
  10. 计算智能学习1_感知机原理_水果生熟分类器_matlab实现