虚拟内存技术的前世今生

在20世纪60年代及70年代早期 , 计算机内存十分昂贵 , 而随着计算机的发展 , 计算机应用程序越来越大 , 系统内存无法满足应用程序的需求 , 虚拟内存技术应运而生 , 它可使内存耗量大的软件运行在实际内存容量小的计算机上 , 在此基础上 , 后续又引入一些安全及可靠性相关的特性 , 使得虚拟内存技术更加得到市场的青睐 。
1940年代和1950年代 , 所有的大型程序都必须包含一个用于管理主存和辅存的逻辑 , 如Overlaying技术 。虚拟内存技术的引入不止用于扩展主存 , 还可以使此类扩展尽可能让编程人员易于使用 。多数早期系统为了让多程序或多任务成为可能 , 采用把内存分给多个程序的做法 , 而不是使用虚拟内存技术 , 如PDP-10 。
到1956年 , 虚拟内存技术概念首次由德国Technische Universität Berlin物理学家Fritz-Rudolf Güntsch于他的博士论文《Logical Design of a Digital Computer with Multiple Asynchronous Rotating Drums and Automatic High Speed Memory Operation》里提及:它描述了一个主存大小为6*100字大小 , 地址空间大小为1000*100字的机器 , 该机器由硬件自动在主存和辅存之间搬移块数据 。
在虚拟内存技术里占重要地位的换页技术首次在曼彻斯特大学(University of Manchester)实现 , 以用来扩展Atlas计算机的工作内存 , 将16384字大小的主存与98304字大小的辅存结合起来 。Atlas官方发布时间为1962年 , 但换页机制的原型在1959年就已经完成 。在1961年 , Burroughs Corporation独立发布第一个支持虚拟内存的商用计算机 , B5000 , 但其使用的段式技术而不是页式技术 。
虚拟内存技术在主流操作系统里实现之前 , 有很多问题兹待解决 , 如动态地址转换需要昂贵且极难实现的专用硬件 , 乃至最初的实现甚至降低了内存的访问速度 。这导致很多人担心新的系统层算法使用辅存会比之前的应用层算法效率更低 。直到1969年 , 有关在商用计算机上应用虚拟内存技术的争辩终于划上句号 , 由David Sayre带领的IBM研究团队展示出他们的虚拟内存overlay系统可以比手动控制的运行得更好 。在1970年代 , 运行基于虚拟存储技术操作系统的IBM 370提供了一个让商业用户将多个老系统迁移到更少却更强大的大型机上的手段 , 这大大提高了性价比 。世界上首台引入虚拟内存的小型机是Norwegian NORD-1 , 到1970年代 , 其他小型机也相继实现了虚拟内存 。
X86架构上首次引入虚拟内存技术的CPU是Intel 80286 , 但其采用的段交换技术并没有有效的增加段大小 , 之后的Intel 80386开始支持换页技术 。

虚拟内存技术的前世今生

文章插图
虚拟内存技术发展时间线
【虚拟内存技术的前世今生】虚拟内存技术作为一种内存管理技术 , 使得操作系统可以结合软硬件技术将程序使用的地址 , 即虚拟地址 , 映射到物理地址 , 使得:
  • 程序可独占全部虚拟地址空间:各程序间地址不冲突 , 因为有自己的页表 , 同样的虚拟地址可以映射到不同的物理地址;
  • 程序可拥有连续的地址空间:可以把零碎的物理地址映射成连续的地址空间 。
操作系统管理着虚拟地址到物理地址的映射关系 , 进行地址映射依赖的CPU硬件一般指的是内存管理单元(MMU,Memory Management Unit),它负责根据页表将虚拟地址自动映射为物理地址 。
虚拟内存技术的最大好处在于使应用程序免于管理内存 , 增加安全性 , 并且使程序在理论上可用内存空间不受物理实际内存大小的限制 。
需要注意的是 , 虽然多数的支持虚拟内存技术的现代操作系统的每个进程运行在它自己独有的地址空间 , 就好像每个程序都独占全部虚拟地址空间 。但是嵌入式操作系统和其他专用的需要快速响应的计算机系统并不使用虚拟内存技术 , 一个因为是虚拟内存可能触发不可预知的延时 , 特别是当需要从辅存里读数据时;另外一个是因为将虚拟地址转换为物理地址一般是需要硬件支持的 , 而并不是所有嵌入式系统使用的CPU都带此功能 。
虚拟地址空间比实际的物理内存容量大 , 必然会引发内存和外部存储设备之间的数据交换 , 在20世纪60年代 , 早期的虚拟内存技术进行内存交换时 , 将整个应用程序都从内存交换到硬盘或外部存储介质上 , 并将另外一个程序从硬盘或外部存储介质交换到内存上运行 , 而并不是按内存的页来替换 , 被交换出内存的程序如果是正在运行中 , 则先挂起 。对于大程序 , 为了减少占用内存 , 可能将程序分成多份 , 使它们可以在不同的时间占用同一份内存 。但这种方法不是一种换页的方法 , 它仅仅减少程序的内存占用空间 。后续的架构使用内存分段(memory segmentation),各程序段作为一个整体在硬盘和内存之间进行交换 。程序段包含程序所有代码的代码段或数据段 , 这些段必须处在连续的内存空间里 , 因此需要通过额外的计算和搬移算法来解决内存空间碎片化的问题 。这之后发明了页表 , 这让处理器工作在抽象的连续的址空间上 , 而页则成为了内存和硬盘之间交换的基本单位 。


推荐阅读