基本存储管理

  • 无存储器抽象
  • 一种存储器抽象:地址空间
    • 地址空间
    • 交换技术
    • 空闲内存管理

存储管理

程序员对存储的要求

  • 不易丢失

存储器分类

  • cache:快速、昂贵、数量小
  • 主存:中速、中等价格
  • 磁盘:慢速、便宜、容量大

存储管理程序处理存储器层次

操作系统中管理存储器层次的部分称为存储器管理程序(memory manager)。它的任务是记录哪些内存在使用,哪些内存是空闲的,在进程需要时为其分配存储空间,在进程使用完毕后释放存储空间,以及当内存无法装入所有进程时,管理内存和磁盘间的交换。

存储管理任务

  • 内存分配和回收
  • 内存扩充技术
  • 重定位
  • 存储保护

无存储器抽象

单道程序

最简单的存储抽象就是没有抽象。

早期的大型机(20世纪60年代前)、小型机(70年代前)、个人计算机(80年代前)都没有存储器抽象。每个程序直接访问物理内存。

内存中不能同时运行两个程序。

三种单道程序的存储器模型

同一时刻只运行一道程序,由程序和操作系统共享内存

  1. 第一种模型曾用于大型机和小型机,不过几乎不再使用了
  2. 第二种模型用于某些掌上机和嵌入式系统
  3. 第三种模型曾用于早期的个人计算机(例如,运行MS-DOS),其中位于ROM系统部分称为BIOS(Basic Input Output System,基本输入输出系统)

组织存储的三种简单方式

多道程序

除了在简单的嵌入式系统中,几乎不再使用单道程序了。大部分现在系统都允许同时运行多个程序。

同时运行多个进程意味着当某个进程在等在I/O结束而阻塞时,另一个进程可以使用CPU,因此,多道程序提高了CPU的利用率。

网络服务器通常可以同时运行多个进程(为不同的客户),不过现在大多数客户(即台式机)机也具备了多道程序能力。

无内存抽象的多道程序

  1. 使用交换技术:把当前内存中的所有内容保存到磁盘文件中,把下一个程序读入内存运行。保证某一时间内存中只有一个程序。
  2. 使用硬件的帮助:保护键。利用保护键阻止进程间相互干扰。

一种存储器抽象:地址空间

地址空间的概念

  • 8位电话号码的地址空间:0000 0000 ~ 9999 9999
  • IPv4地址的地址空间:\(0 - 2^{32}-1\)

地址空间

地址空间:一个进程可用于寻址内存的一套地址集合

每个进程都有一个自己的地址空间。并且这个地址空间独立于其他进程的地址空间

进程的地址空间:

  • 32位机:\(2^{32}\)字节,即4G字节
  • 寻址范围:\(0 - 2^{32}-1\)

地址空间VS存储空间

地址空间

源程序经编译后目标程序所在的一个地址范围,同城从0开始——逻辑地址

存储空间

内存中的物理存储单元的集合——物理地址

重定位

逻辑地址到物理地址的映射。在多道程序系统中,内存通常由多个进程共享;进程通常在内存和磁盘间调入、调出。因此,无法确定程序将会载入到内存的什么地方。用户在程序中使用的是逻辑地址。用于内存访问之前要转为物理地址——重定位。

重定位分为两种:

  • 静态重定位
  • 动态重定位

静态重定位

当程序载入内存时直接修改指令。载入分区1的程序,在每个地址上加100K,载入分区2的程序,在每个地址上加200K,等等。为了在载入时对程序重定位,链接程序必须在产生的二进制代码程序中包含列表或者未影响,由它们指出哪些程序字的地址需要重定位,而哪些时操作码、常熟或者其他一些不需要重定位的项。OS/MFT系统就是这样工作的。

动态重定位—基址寄存器和界限寄存器

基址寄存器:程序的起始物理地址

界限寄存器:程序的长度

在访问内存时,进程生成的每个地址都自动加上基址寄存器的内容。因此,如果基址寄存器的值为100K,CALL 100指令始值上被转换为CALL 100K+100,指令本身不必修改。

边界寄存器自动检查指令,以确保它们没有试图访问当前分区以外的地址。由硬件保护基址和边界寄存器,以防止用户程序修改它们。

固定分区的多道程序

  • (a)每个固定内存分区都有一个单独的输入队列
  • (b)只有单个输入队列的固定内粗分区

可变分区的多道程序

交换(swapping)

如果计算机的物理内存足够大,可以保存所有进程,那么所有方案都可行

实际上,所有进程所需的RAM数量总和通常要远远超出存储器所能够支持的范围

处理内存超载的方法:

  • 交换、覆盖
  • 虚拟内存

交换:把一个进程完整地调入内存,使该进程运行一段时间,然后把它存回磁盘。空闲进程主要存储在磁盘上,所以当它们不运行时就不会占用内存。

内存分配随着进程进出内存而变化

  • 阴影区域表示的是未使用的内存

当交换在内存中造成很多空洞时,通过将所有进程尽可能地向下移动,以组合成一大块,该技术称为内存压缩(memory compaciton)。该操作不经常进行,因为要耗费大量的CPU时间。例如,一台256MB的计算机40ns可以复制4个字节,它需要花费大约2.7秒钟来压缩全部内存。

  1. 进程创建或换入时,内存的分配

  2. 根据进程需要的大小进行分配

  3. 大部分进程在运行时都要增长,为减少因内存区域不够而引起的进程交换和移动嗦产生的开销,为进程分配一些额外的内存,如下图

    (a)为增上的数据段预留空间

    (b)为增上的数据段和堆栈段预留空间

内存管理

分配内存时,操作系统必须对其进行管理。由两种方式可用来跟踪内存使用情况:

  • 位图
  • 链表

使用位图的存储管理

使用位图:内存被划分成分配单元,可能小到几个字,也可能大到几千字节。每个分配单元对应于位图中的一位,0表示空闲,1表示占用(或者相反)。

内存分配:把一个占有K个分配单元的进程调入内存时,存储管理器搜索位图,在为途中找出有K个连续0的串。

分配单元的大小时重要的设计课题。分配单元越小,位图越大

位图提供了一个简单的方法来记录固定容量的内存字,因为位图的大小只依赖于内存和分配单元的大小。

缺点:查找位图中指定长度的连续0串时耗时的操作。

  • (a)有5个进程和3个空闲区的内存
    • 刻度表示内存分配单元,阴影区域表示空闲(在位印象中用0表示)
  • (b)对应的位图
  • (c)用链表表示同样的信息

使用链表的存储管理

使用链表:维护一个记录已分配和空闲内存段的链表。其中,段是指一个进程,或者是两个进程间的空闲区。

表中的每一项都只当了如下内容:空闲区(H)还是进程(P)、起始地址、长度以及指向下一项的指针。

使用链表的存储管理—内存分配

当有进程新建或换入时,要查找链表进行内存分配

最简单的算法时首次适配(first fit)。存储器管理程序沿着段链表搜索,直到找到一个足够大的空闲区。除非该空闲区的大小和要分配的大小正好一样,否则将该空闲区分为两部分,一部分让进程使用,另一部分为未用的内存。首次适配算法是一种快速算法,因为它尽可能少搜索。

对首次适配算法的一个小变种为下次适配(next fit),它的工作方式和首次适配算法相同,不同点在于每次找到合适的空闲区时都记录当时的位置,以便在下次寻找空闲区时从上次结束的地方开始搜索,而不是每次都从头开始

最佳适配(best fit)算法搜索整个链表,找出足够大的最小空闲区。最佳适配算法试图找出最接近实际需要的空闲区,而不是使用将要需要的大空闲区。

为了避免最接近适配的空闲区回分裂出绩效空洞的问题,有人考虑到最差适配(worst fit),即总是分配最大的空闲区,使分裂出来的空闲区够大从而可以继续使用。

使用链表的存储管理—内存回收

进程X终止前后的四种情况

猜你喜欢

转载自www.cnblogs.com/iamfatotaku/p/12742883.html