主存(RAM) 是一件非常重要的资源,必须要小心对待内存。虽然目前大多数内存的增长速度要比 IBM 7094 要快的多,但是,程序大小的增长要比内存的增长还快很多。正如帕金森定律说的那样:不管存储器有多大,但是程序大小的增长速度比内存容量的增长速度要快的多。下面我们就来探讨一下操作系统是如何创建内存并管理他们的。
经过多年的探讨,人们提出了一种 分层存储器体系(memory hierarchy),下面是分层体系的分类
顶层的存储器速度最高,但是容量最小,成本非常高,层级结构越向下,其访问效率越慢,容量越大,但是造价也就越便宜。
操作系统中管理内存层次结构的部分称为内存管理器(memory manager),它的主要工作是有效的管理内存,记录哪些内存是正在使用的,在进程需要时分配内存以及在进程完成时回收内存。
下面我们会对不同的内存管理模型进行探讨,从简单到复杂,由于最低级别的缓存是由硬件进行管理的,所以我们主要探讨主存模型和如何对主存进行管理。
无存储器抽象
最简单的存储器抽象是没有存储。早期大型计算机(20 世纪 60 年代之前),小型计算机(20 世纪 70 年代之前)和个人计算机(20 世纪 80 年代之前)都没有存储器抽象。每一个程序都直接访问物理内存。当一个程序执行如下命令:
MOV REGISTER1, 1000
计算机会把位置为 1000 的物理内存中的内容移到 REGISTER1 中。因此,那时呈现给程序员的内存模型就是物理内存,内存地址从 0 开始到内存地址的最大值中,每个地址中都会包含一个 8 位位数的单元。
所以这种情况下的计算机不可能会有两个应用程序同时在内存中。如果第一个程序向内存地址 2000 的这个位置写入了一个值,那么此值将会替换第二个程序在该位置上的值,所以,同时运行两个应用程序是行不通的,两个程序会立刻崩溃。
不过即使存储器模型就是物理内存,还是存在一些可选项的。下面展示了三种变体
在上图 a 中,操作系统位于 RAM(Random Access Memory) 的底部,或像是图 b 一样位于 ROM(Read-Only Memory) 顶部;而在图 c 中,设备驱动程序位于顶端的 ROM 中,而操作系统位于底部的 RAM 中。图 a 的模型以前用在大型机和小型机上,但现在已经很少使用了;图 b 中的模型一般用于掌上电脑或者是嵌入式系统中。第三种模型就应用在早期个人计算机中了。ROM 系统中的一部分成为 BIOS (Basic Input Output System)。模型 a 和 c 的缺点是用户程序中的错误可能会破坏操作系统,可能会导致灾难性的后果。
按照这种方式组织系统时,通常同一个时刻只能有一个线程正在运行。一旦用户键入了一个命令,操作系统就把需要的程序从磁盘复制到内存中并执行;当进程运行结束后,操作系统在用户终端显示提示符并等待新的命令。收到新的命令后,它把新的程序装入内存,覆盖前一个程序。
在没有存储器抽象的系统中实现并行性的一种方式是使用多线程来编程。由于同一进程中的多线程内部共享同一内存映像,那么实现并行也就不是问题了。
运行多个程序
但是,即便没有存储器抽象,同时运行多个程序也是有可能的。操作系统只需要把当前内存中所有内容保存到磁盘文件中,然后再把程序读入内存即可。只要某一时间只有一个程序,那么就不会产生冲突。
在额外特殊硬件的帮助下,即使没有交换功能,也可以并行的运行多个程序。IBM 360 的早期模型就是这样解决的
System/360是 IBM 在1964年4月7日,推出的划时代的大型电脑,这一系列是世界上首个指令集可兼容计算机。
在 IBM 360 中,内存被划分为 2KB 的区域块,每块区域被分配一个 4 位的保护键,保护键存