在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),各程序段作為一個整體在硬盤和內存之間進行交換。程序段包含程序所有代碼的代碼段或數據段,這些段必須處在連續的內存空間里,因此需要通過額外的計算和搬移算法來解決內存空間碎片化的問題。這之后發明了頁表,這讓處理器工作在抽象的連續的址空間上,而頁則成為了內存和硬盤之間交換的基本單位。
當軟件試圖訪問一個不在內存中的頁時,處理器將該操作當作Page fault對待,這會將系統控制權由程序轉到操作系統,操作系統則:
1. 確定數據在硬盤上的位置;
2. 獲取RAM中一個空的頁幀以存放數據;
3. 加載數據到該頁幀;
4. 更新頁表指向該頁幀;
5. 控制權返回給程序,重新執行導致Page fault的指令。
如果所有頁幀都在使用中,則操作系統必須選擇其中一個頁幀給程序使用。如果被驅逐的頁幀由另外一個程序動態申請并保存了數據,又或者在該頁幀數據讀到RAM后被程序修改了(換句話說,該頁幀是"臟"的了),則該頁幀在被釋放前,數據必須回寫到硬盤里。如果一個程序之后又引用了該頁幀,則產生一個Page fault,觸發切頁操作,該頁被再次讀到RAM里。
上世紀60年代的大型機的操作系統和80年代中期的個人電腦操作系統多數都沒有虛擬內存功能,除了以下大型機操作系統:
· Altas的Altas Supervisor
· Electrologica X8的THE multiprogramming system(純軟件的虛擬內存技術)
· Burroughs B5000的MCP
· IBM System/360 Model 67的MTS,TSS/360,CP/CMS
· GE 645的Multics
· RCA Spectra 70/46的Time Sharing Operating System
以及個人電腦Apple的Lisa,它的操作系統支持虛擬內存。
<完>