操作系统学习笔记(十四):覆盖、交换

接下来几节都是对虚拟存储的讲解。虚拟存储是非连续存储管理的扩展。通过将内存中的数据暂存到外存的方式,为进程提供更大的内存空间。虚拟存储出现的主要原因是因为程序规模的增长速度远远大于存储器容量的增长速度,导致内存空间不够用。其实针对内存空间不够用的问题有多重解决方案,比如覆盖、交换、虚拟存储。它们的概念如下:

  • 覆盖:应用程序手动把需要的指令和数据加载到内存;
  • 交换:操作系统自动把暂时不能执行的程序保存到外存中;
  • 虚拟存储:在有限的内存中,以页为单位自动装入更多更大的程序

本小节首先对覆盖和交换进行讲解。

覆盖:

目标:

在较小的可用内存中运行较大的程序。

方法:

依据程序逻辑,将程序划分为若干功能相对独立的模块,不会同时执行的模块共享同一块内存区域。具体有以下几点:

  • 必要部分(常用功能)的代码和数据常驻内存;
  • 可选部分(不常用功能)放在其它程序模块中,只在需要时加载到内存;
  • 不存在调用关系的模块可以相互覆盖,共用同一块内存区域。

具体操作如下:假设有一个程序总大小190K,调用关系如下图。我们按照上述原则对程序进行分组,比如A单独一组,B与C没有调用关系因此B、C一组,D、E、F没有调用关系分为一组,分配内存时按照组内最大的模块分配内存,如图中右侧,A划分20K,B、C这组分配50K,D、E、F这组分配40K,按照需求向内存中加载。这样这个程序可以在内存大小为110K的机器中运行。那么这种分组方式是不是最优的呢?答案是否定的,我们可以将大小相近的分到一组,比如A单独一组20K,B、E、F无调用关系50K,C、D无调用关系30K,总共需要100K内存。因此不同的分组方式对内存的需求是不一样的。想要严格讨论哪种方式内存需求最小是很复杂的。

操作系统学习笔记(十四):覆盖、交换

缺点:

  • 增加编程困难。需要程序员划分功能模块,并确定模块之间的覆盖关系,增加了编程的复杂度;
  • 增加执行时间。需要将各程序模块在内存模块中换入换出,实际是用时间换空间。

交换:

交换与覆盖讨论的尺度是不太一样的。覆盖是一个程序内,如果无法全部加载到内存,而交换是内存足够放一个程序,而无法放多个程序。

目标:

增加正在运行或需要运行的程序的内存。

实现方法:

  • 可将暂时不能运行的程序放到外存;
  • 换入换出的基本单位是进程;
  • 换出是把一个进程的整个地址空间保存到外存;
  • 换入是把一个进程的整个地址空间从外存加载到内存。

问题:

  • 交换时机:只当内存空间不足或有不足的可能的时候才进行换入换出;
  • 交换区大小:存放所有用户进程的所有内存映像的拷贝;
  • 程序换入时的重定位:换入时不是放回原处,因此需要程序运行过程中采用动态地址映射。

覆盖与交换对比:

覆盖:

  • 只能发生在没有调用关系的模块之间;
  • 程序员须给出模块之间的逻辑覆盖关系;
  • 发生在运行程序的内部模块间。

交换:

  • 以进程为单位;
  • 不需要模块间的逻辑覆盖关系;
  • 发生在内存进程间。

交换是可以通过操作系统实现的,而覆盖是无法在操作系统中实现的,必须有程序员具体实现,增大了编程的难度。