计算机操作系统(第四版) 第四章 存储器管理 (!前两节+清晰的总结!)

1 引言

     存储器在计算机中占有重要的地位,程序的执行、文件的存储、数据的流动等等。今天和大家分享的是存储器的相关知识。

2 存储器管理

2.1 存储器的层次结构

2.1.1 多级存储器结构

      对于通用计算机而言,存储层次至少应具有三级:最高层为CPU寄存器,中间为主存,最底层是辅存。

      在较高档的计算机中,还可以根据具体的功能分工细划为寄存器、高速缓存、主存储器、磁盘缓存、固定磁盘、可移动存储介质等6层。
      在存储层次中越往上,存储介质的访问速度越快,价格也越高,相对存储容量也越小。
寄存器、高速缓存、主存储器和磁盘缓存均属于操作系统存储管理的管辖范畴,掉电后它们存储的信息不再存在。

固定磁盘和可移动存储介质属于设备管理的管辖范畴,它们存储的信息将被长期保存。



什么是操作系统的存储管理?

在计算机系统存储层次中,寄存器和主存储器又被称为可执行存储器。

操作系统的存储管理,负责对可执行存储器的分配、回收以及提供在存储层次间数据移动的管理机制。

    -- 例如主存与磁盘缓存、高速缓存与主存间的数据移动等。

2.1.2 主存储器与寄存器

1.主存储器
      主存储器(简称内存或主存)是计算机系统中一个主要部件,用于保存进程运行时的程序和数据,也称可执行存储器。
其容量对于当前的微机系统和大中型机,可能一般为数十MB到数GB,而且容量还在不断增加,而嵌入式计算机系统一般仅有几十KB到几MB。
      CPU的控制部件只能从主存储器中取得指令和数据,数据能够从主存储器读取并将它们装入到寄存器中,或者从寄存器存入到主存储器。
      CPU与外围设备交换的信息一般也依托于主存储器地址空间。

由于主存储器的访问速度远低于CPU执行指令的速度,为缓和这一矛盾,在计算机系统中引入了寄存器和高速缓存。

2.寄存器
寄存器访问速度最快,完全能与CPU协调工作,但价格却十分昂贵,因此容量不可能做得很大。
寄存器的长度一般以字(word)为单位。
寄存器的数目,对于当前的微机系统和大中型机,可能有几十个甚至上百个;而嵌入式计算机系统一般仅有几个到几十个。

寄存器用于加速存储器的访问速度,如用寄存器存放操作数,或用作地址寄存器加快地址转换速度等。 

2.1.3 高速缓存和磁盘缓存

1.高速缓存
高速缓存是现代计算机结构中的一个重要部件,其容量大于或远大于寄存器,而比内存约小两到三个数量级左右,从几十KB到几MB,访问速度快于主存储器。
程序执行的局部性原理:程序在执行时将呈现出局部性规律,在一较短的时间内,程序的执行仅局限于某个部分。

根据程序执行的局部性原理,将主存中一些经常访问的信息存放在高速缓存中,减少访问主存储器的次数,可大幅度提高程序执行速度。

2.磁盘缓存
      磁盘的I/O速度远低于对主存的访问速度,因此将频繁使用的一部分磁盘数据和信息,暂时存放在磁盘缓存中,可减少访问磁盘的次数。
      磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的存储空间,来暂存从磁盘中读出(或写入)的信息。
主存也可以看做是辅存的高速缓存。

因为,辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能输出到辅存。 

      一个文件的数据可能出现在存储器层次的不同级别中,例如,一个文件数据通常被存储在辅存中(如硬盘),当其需要运行或被访问时,就必须调入主存,也可以暂时存放在主存的磁盘高速缓存中。
大容量的辅存常常使用磁盘,磁盘数据经常备份到磁带或可移动磁盘组上,以防止硬盘故障时丢失数据。

有些系统自动地把老文件数据从辅存转储到海量存储器中,如磁带上,这样做还能降低存储价格。 

2.2 程序的链接和装入

在多道程序环境下,要使程序运行,必须先为之创建进程。
创建进程的第一件事,便是将程序和数据装入内存。
如何将一个用户源程序变为一个可在内存中执行的程序,通常都要经过以下几个步骤:
编译,由编译程序(Compiler)将用户源代码编译成若干个目标模块(Object Module);
链接,由链接程序(Linker)将编译后形成的一组目标模块,以及它们所需要的库函数链接在一起,形成一个完整的装入模块(Load Module)

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

2.2.1 程序的装入

为了方便,介绍一个无需链接的单个目标模块的装入过程。有三种方式:
绝对装入方式
可重定位装入方式

动态运行时装入方式

1.绝对装入方式(Absolute Loading Mode)
在编译时,如果知道程序将驻留在内存的什么位置,那么,编译程序将产生绝对地址的目标代码。
   - 例如,事先已知用户程序(进程)驻留在从R处开始的位置,则编译程序所产生的目标模块(即装入模块)便从R处开始向上扩展。
绝对装入程序按照装入模块中的地址,将程序和数据装入内存。
装入模块被装入内存后,由于程序中的逻辑地址与实际内存地址完全相同,故不须对程序和数据的地址进行修改。 

程序中所使用的绝对地址,既可在编译或汇编时给出,也可由程序员直接赋予。

缺点:
程序员直接给出绝对地址时,不仅要求程序员熟悉内存的使用情况,而且一旦程序或数据被修改后,可能要改变程序中的所有地址。

因此,通常是宁可在程序中采用符号地址,然后在编译或汇编时,再将这些符号地址转换为绝对地址。 

2.可重定位装入方式(Relocation Loading Mode) 
绝对装入方式只能将目标模块装入到内存中事先指定的位置。
在多道程序环境下,编译程序不可能预知所编译的目标模块应放在内存的何处,因此,绝对装入方式只适用于单道程序环境。
在多道程序环境下,所得到的目标模块的起始地址通常是从0开始的,程序中的其它地址也都是相对于起始地址计算的。

此时应采用可重定位装入方式,根据内存的当前情况,将装入模块装入到内存的适当位置。 

3.动态运行时装入方式(Dynamic Run-time Loading)
可重定位装入方式可将装入模块装入到内存中任何允许的位置,故可用于多道程序环境;
但这种方式并不允许程序运行时在内存中移动位置。因为,程序在内存中的移动,意味着它的物理位置发生了变化,这时必须对程序和数据的地址(是绝对地址)进行修改后方能运行。

然而,实际情况是,在运行过程中它在内存中的位置可能经常要改变,此时就应采用动态运行时装入的方式。 

动态运行时装入
动态运行时的装入程序在把装入模块装入内存后,并不立即把模块的相对地址转换为绝对地址;
地址的转换要等到程序真正执行的时候才执行。

为了使地址转换步影响指令的执行速度,需要一个重定位寄存器的支持。 

2.2.2 程序的链接

4.2.2 程序的链接
  根据链接时间的不同,可把链接分成如下三种:
  (1) 静态链接。在程序运行之前,先将各目标模块及它们所需的库函数,链接成一个完整的装配模块,以后不再拆开。我们把这种事先进行链接的方式称为静态链接方式。
  (2) 装入时动态链接。这是指将用户源程序编译后所得到的一组目标模块,在装入内存时,采用边装入边链接的链接方式。

  (3) 运行时动态链接。这是指对某些目标模块的链接,是在程序执行中需要该(目标)模块时,才对它进行的链接。 

1.静态链接方式(Static Linking)

  (1) 对相对地址进行修改。在由编译程序所产生的所有目标模块中,使用的都是相对地址,其起始地址都为0,每个模块中的地址都是相对于起始地址计算的。在链接成一个装入模块后,原模块B和C在装入模块的起始地址不再是0,而分别是L和L+M,所以此时须修改模块B和C中的相对地址,即把原B中的所有相对地址都加上L,把原C中的所有相对地址都加上L+M。 

(2) 变换外部调用符号。将每个模块中所用的外部调用符号也都变换为相对地址,如把B的起始地址变换为L,把C的起始地址变换为L+M。

    这种先进行链接所形成的一个完整的装入模块,又称为可执行文件。通常都不再拆开它,要运行时可直接将它装入内存。这种事先进行链接,以后不再拆开的链接方式,称为静态链接方式。 

2.装入时动态链接(Load-time Dynamic Linking)
目标模块在装入内存时边装入边链接

    即在装入一个目标模块时,若发生一个外部模块调用事件,将引起装入程序去找出相应的外部目标模块,并将它装入内存并修改相对地址。

装入时动态链接方式有以下优点:
  (1) 便于修改和更新。对于经静态链接装配在一起的装入模块,如果要修改或更新其中的某个目标模块,则要求重新打开装入模块。这不仅是低效的,而且有时是不可能的。若采用动态链接方式,由于各目标模块是分开存放的,所以要修改或更新各目标模块是件非常容易的事。 

(2) 便于实现对目标模块的共享。在采用静态链接方式时,每个应用模块都必须含有其目标模块的拷贝,无法实现对目标模块的共享。但采用装入时动态链接方式,OS则很容易将一个目标模块链接到几个应用模块上,实现多个应用程序对该模块的共享。

3.运行时动态链接(Run-time Dynamic Linking)

  在许多情况下,应用程序在运行时,每次要运行的模块可能是不相同的。但由于事先无法知道本次要运行哪些模块,故只能是将所有可能要运行到的模块都全部装入内存,并在装入时全部链接在一起。显然这是低效的,因为往往会有些目标模块根本就不运行。比较典型的例子是作为错误处理用的目标模块,如果程序在整个运行过程中都不出现错误,则显然就不会用到该模块。 

近几年流行起来的运行时动态链接方式,是对上述在装入时链接方式的一种改进。这种链接方式是将对某些模块的链接推迟到程序执行时才进行链接,亦即,在执行过程中,当发现一个被调用模块尚未装入内存时,立即由OS去找到该模块并将之装入内存,把它链接到调用者模块上。凡在执行过程中未被用到的目标模块,都不会被调入内存和被链接到装入模块上,这样不仅可加快程序的装入过程,而且可节省大量的内存空间。 

3 结束语

晚安!

猜你喜欢

转载自blog.csdn.net/chen_yongbo/article/details/80588135