[操作系统] 地址空间和交换技术

来源:互联网 发布:安德迈 知乎 编辑:程序博客网 时间:2024/06/04 03:57

地址空间和交换技术


  • 地址空间和交换技术
    • 地址空间的概念
    • 基址寄存器和界限寄存器
    • 内存超载
    • 交换技术
      • 预留空间
      • 空闲内存管理
    • 链表存储管理中用来创建进程的算法


1. 地址空间的概念

在最初系统中没有对内存的抽象,直接使用物理地址进行存储,这种方法会带来严重的问题。

  1. 如果用户程序可以寻址内存的每个字节,它们就可以容易地破坏操作系统。从而使操作系统停止运行
  2. 想要同时运行多个程序很困难,因为使用物理地址很容易将数据覆盖。

要保证多个应用程序同时存在于内存并且不互相影响,要解决两个问题:保护重定位

一个很好的解决方法是创造一个内存抽象:地址空间。地址空间为程序创造了一种抽象的内存,地址空间是一个进程可用于寻址内存的一套地址集合。每个进程都有一个自己的地址空间,并且这个地址空间独立于其他进程的地址空间(在特殊情况下想要共享除外)。例如,电话号码00000000000 ~ 99999999999就是一个地址空间。

2. 基址寄存器和界限寄存器

使用地址空间的困难点在于给每个程序一个自己的地址空间,假如A程序想要使用的地址为28,B程序想要使用的地址也为28。两个程序同时运行,我们不能让这两个程序相互影响,就要让他们想要使用的**逻辑地址**28对应不同的物理地址。

解决这个问题的一种方法是动态重定位。为每个CPU配置两个特殊的寄存器,基址寄存器界限寄存器。当程序运行时,程序的起始物理地址装载到基址寄存器,长度装载到界限寄存器。这样程序在执行命令时,如果使用逻辑地址就会被解释为基址寄存器存储的物理地址。例如,此时程序想要访问逻辑地址28,使用命令 “JMP 28”,此时基址寄存器中的值为16412,硬件自动把这条指令解释为”JMP 16412”。

使用这种方法的缺点是,每次访问内存都需要进行加法和比较

3. 内存超载

当所有要执行的进程所需要的内存大于计算机的物理内存时,就不能把所有进程一直保存在内存中。这种情况叫做内存超载。要想解决这种问题,有两种方法。

  1. 交换技术
    即把一个进程完整调度内存,使该进程运行一段时间,然后把它存回磁盘。空闲进程主要存储在磁盘上,就不会占用内存。

  2. 虚拟内存
    可以使程序在只有一部分被调入内存的情况下运行。

4. 交换技术

内存交换技术

如图所示,阴影区域表示未使用的内存。开始时内存中只有进程A。之后创建进程B和C或者从磁盘将它们还如内存。d图显示A被交换到磁盘,D被调入到内存,然后B被调出,A再次被调入。

1. 预留空间

通过图片可见,使用这种方法,内存中有很多小的空闲区(阴影),这些小的空闲区大部分无法放置合适的进程,就会造成浪费。通过把所有进程向下移动,将这些空闲区合在一起,可以节省空间,这种方法叫做内存紧缩。但是这个操作会耗费大量CPU时间。

使用这种方法我们需要注意一个问题,即如果进程大小不是一成不变的而是动态的该怎么解决。若该进程与空闲区相邻,可以使用空闲区来将该进程所占内存扩大。但如果该进程与其他进程相邻,则无法扩大,此时只能交换出一个或多个进程。

为了解决这个问题,在为进程分配内存空间时,可以为它们分配一些额外的内存。而写回磁盘时,只写回实际使用的内存。

动态内存分配

a图为给进程分配多余空间的普通方法。如果进程有两个可增长段,如数据段和堆栈段,则可以使用b中的方法。

2. 空闲内存管理

在动态分配内存时,操作系统必须对内存进行追踪和管理。

  1. 使用位图的存储管理
    内存被划分为几个字到几千字节的分配单元,每个分配单元对应于为位图中的一位,0表示空闲,1表示占用(或者相反)。分配单元越小,位图越大。32n位的内存需要n位位图。再决定把一个占k个分配单元的进程调入内存中时,存储管理器需要搜索位图,在位图中找出有个k个连续为0的串。缺点是比较耗时。

    空闲内存管理

  2. 链表存储管理
    链表中的结点或者是一个进程,或者是两个进程间的空闲区。每一个结点包含:空闲区,进程的指示标志、起始地址、长度。当进程终止时,更新非常直接,如果邻居没有空闲去,只把自己变为空闲区就可以。如果邻居有空闲区则把该进程原有的地址与空闲区合并。所以双链表更好,因为便于找到前后邻居并合并。

    链表存储管理

5. 链表存储管理中用来创建进程的算法

假设存储管理器知道要为进程分配多大内存。

  1. 首次适配
    存储器沿着段链进行搜索,找到第一个足够大的空闲区,将空闲区的一部分给进程使用,另一部分变为新的空闲区(除非大小正好一样)。这种方法速度很快。

  2. 下次适配
    工作方式与首次适配相似,但是不同于首次适配每次从头开始寻找,下次适配会记录下上次分配的位置,然后从上次分配过的地方开始。

  3. 最佳适配
    搜索整个链表,找到能容纳进程的最小空闲区。浪费时间,并且会产生许多无用的小空闲区。

  4. 最差适配
    与最佳适配相反,该方法总是总是分配最大空闲区给进程。

    如果想要增加以上4个算法速度,可以为进程和空闲区维护各自的链表。但会增加内存释放速度,因为要将结点从进程链表删除,并加入到空闲区链表。可以将空闲区链表进行增序排序,以减少最佳适配的速度。当单独维护空闲区时,可以直接用空闲区存储信息,每个空闲区的第一个字可以为大小,第二个字可以指向下一个空闲区。
  5. 快速适配:为常用大小的空闲区维护单独列表。例如有一个n项的表。表的第一项指向大小4KB空闲区,第二项为8KB,第三项为12KB。以此类推,21KB的空闲区可以放在代表20KB链表中,也可以单独放置在特别链表中。

参考书目:现代操作系统第三版

原创粉丝点击