内存管理的环境
程序要运行,必须先加载到内存。但在很久以前,准确地说是在操作系统出现以前,程序并不需要加载到内存才能运行。实际上,在那个已经久远的年代里,程序曾经是存放在卡片上,计算机每读一张卡片,就运行一条指令。因此,程序是直接从卡片到执行。
但这种从外部存储媒介上直接执行指令的做法效率极低,且灵活性很差。因此,人们发明了内存储器来将需要运行的程序先行加载,再自动执行,从而提高效率和灵活性。这也导致了“存储的程序”概念,而存储的程序概念又导致计算机及软件系统的革命性变化。此后,人们对内存的要求是越来越多,越来越高。
理想状态下,程序员对内存的要求是:大容量,高速度和持久性。但程序员面临的物理现实却是一个由缓存、主存、磁盘等组成的一个内存架构。磁带一般不算在内,因为访问不方便。在这个内存的现实架构中,缓存的特点是低容量(相对主存来说).高速度﹑高价格;主存的特点则是中容量,中速度.中价格;磁盘则是大容量.低速度﹑低成本的存储媒介。
很显然,这样一个存储架构需要一个有效的管理机制,而这个管理机制就是内存管理。那什么是内存管理呢? 内存管理就是对内存架构进行管理,使程序在内存架构的任何一个层次上的存放对于用户来说都是一样的。 用户无需担心自己的程序是存在缓存、主存、磁盘还是磁带,反正运行,计算、输出的结果都一样。让内存管理实现这种媒介透明的手段就是虚拟内存,形象的说,虚拟内存就是操作系统提供给用户的另一个“幻象”。这个幻象构建在内存架构的顶端,给用户提供一个比物理主存空间大许多的地址空间。
内存管理的目标
首先,由于多道程序同时存放在内存中,操作系统要保证它们之间互不干扰。所谓的互不干扰就是一个进程不能随便访问另一个进程的地址空间。这是内存管理要达到的第一个目标。
那还有没有别的目标呢?我们看一下程序指令执行的过程。程序指令在执行前被加载到内存,然后从内存中一条条指令读出,然后执行(从硬件层来看,指令的“读取——执行"循环是计算机的基本操作)。每条指令在执行时需要读取操作数和写入运算结果。而要读取操作数,就需要给出操作数所在的内存地址,这个地址不能是物理主存地址。 (不能保证程序运行都会被加载到同一块物理内存)这是因为该程序在何种硬件配置的机器上运行并不能事先确定,操作系统自然不可能对症下药地发出对应于某台机器的物理主存地址。因此, 指令里面的地址是程序空间(虚拟空间)的虚拟地址(程序地址,即程序发出的地址与具体机器的物理主存地址是独立的。 这是内存管理要达到的另外一个目标。
总结来说,内存管理要达到如下两个目标:
1. 地址保护:一个程序不能访问另一个程序地址空间。
2. 地址独立:程序发出的地址应与物理主存地址无关。
而这两个目标就是衡量一个内存管理系统是否完善的标准。它是所有内存管理系统必须提供的基本抽象。当然,不同的内存管理系统在此二者之上还提供了许多其他抽象。
虚拟内存的概念
虚拟内存的概念听上去有点太虚拟,但其实质并不难理解。我们知道,一个程序如果要运行,必须加载到物理主存里。但是,物理主存的容量非常有限。因此,如果要把一个程序全部加载到物理主存,我们所能编写的程序将是很小的程序。它的最大容量受制于主存容量(还要减去操作系统所占的空间和一些临时缓存空间)。另外,即使我们编写的每个程序的尺寸都小于物理主存容量,还是存在一个问题:主存能够存放的程序数量将是很有限的,而这将极大地限制多道编程的发展。
虚拟内存的中心思想是将物理主存扩大到便宜、大容量的磁盘上,即将磁盘空间看作是主存空间的一部分。 用户程序存放在磁盘上就相当于存放在主存内。用户程序既可以完全存放在主存,也可以完全存放在磁盘上,当然也可以部分存放在主存,部分存放在磁盘。而程序执行时,程序发出的地址到底是在主存还是在磁盘则由操作系统的内存管理模块负责判断,并到相应的地方进行读写操作。 事实上,我们可以更进一步,将缓存和磁带也包括进来,构成一个效率、价格、容量错落有致的存储架构。即虚拟内存要提供的就是一个空间像磁盘那样大.速度像缓存那样高的主存储系统,而对程序地址所在位置(缓存、主存、磁盘)的判断则是内存管理系统的一个中心功能。
值得特别指出的是,虚拟内存是操作系统发展历史上的一个革命性突破(当然,它也是使操作系统变得更加复杂的一个主要因素)。因为有了虚拟内存,我们编写的程序从此不再受尺寸的限制(当然还是受制于虚地址空间大小的限制)。
虚拟内存除了让程序员感觉到内存容量大大增加之外,还让程序员感觉到内存速度也加快了。这是因为虚拟内存将尽可能从缓存满足用户访问请求,从而给人以速度提升了的感觉。当然了,容量增大也好,速度提升也好,都是虚拟内存提供的一个幻象,实际上并没有这回事。
操作系统在内存中的位置
从根本上来说,计算机里面运转的程序有两种:管理计算机的程序和使用计算机的程序。操作系统就是管理计算机的程序。而管理者本身也需要使用资源。其中的一个资源就是内存空间。内存管理的第一个问题是操作系统本身在内存中的存放位置。应该将哪一部分的内存空间用来存放操作系统呢?或者说,我们如何将内存空间在操作系统和用户程序之间进行分配呢?