計算機作業系統——虛擬記憶體與實體記憶體

funtrin 發表於 2021-09-20

虛擬記憶體與實體記憶體

如何管理記憶體?

當多個程式同時執行時,如何讓多個應用程式共同使用實體記憶體資源?有兩種簡單的方法:

  1. 使某一個應用程式獨佔所有的記憶體資源。一個程式要執行就將另一個程式的記憶體資料轉存到硬碟中,使要執行的程式獨佔所有記憶體資源。

    • 缺點:硬碟讀寫速度很慢(相對而言),如果應用程式頻繁切換,必然會造成大量時間開銷。
  2. 讓每一個應用程式獨佔一部分記憶體資源。多個應用程式的資料,可以一直儲存在記憶體中,避免了硬碟讀寫的時間開銷。

    • 缺點:無法保證不同應用程式記憶體之間的隔離性,如果應用程式A錯誤讀取或修改了應用程式B的記憶體資料,就會造成嚴重的後果。
    • 缺點:無法保證每個應用程式分到的記憶體地址是連續的,這會增加程式編寫的複雜度。

虛擬記憶體

為了使不同的應用程式高效,安全的使用記憶體,虛擬記憶體應運而生。顧名思義,虛擬記憶體是對實體記憶體的一種抽象,它介於應用程式與實體記憶體之間。應用程式是面向虛擬記憶體編寫的,而不再是面向實體記憶體編寫的。應用程式在執行時只能使用虛擬地址CPU負責將虛擬地址翻譯成實體地址,作業系統負責設定虛擬地址到實體地址的對映。

優點:

  1. 應用程式只能看到自己的虛擬地址空間,從而保證了應用程式之間記憶體的隔離性,使應用程式執行更安全。
  2. 每個應用程式的虛擬記憶體空間是連續的、統一的,從而降低了程式設計的複雜性。

計算機作業系統——虛擬記憶體與實體記憶體

地址翻譯:CPU中的記憶體管理單元(MMU)負責將虛擬記憶體翻譯成實體記憶體。為了加速地址翻譯過程,MMU中還加入了轉址旁路快取(TLB),TLB可以快取一部分虛擬地址到實體地址的對映,從而加速翻譯。

虛擬記憶體是硬體提供的一種功能,而不是作業系統提供的。

分段和分頁

分段和分頁是MMU將虛擬地址翻譯為實體地址的兩種機制。

分段

在分段的機制下,作業系統以“段”(一段連續的實體記憶體)的形式來管理、分配虛擬記憶體和實體記憶體。應用程式的虛擬地址空間由若干個不同大小的段組成,比如:程式碼段、資料段。

每一段都是一個虛擬地址空間,虛擬地址由兩部分組成:段號段內地址。MMU通過段表找到對應的物理段,再通過虛擬地址中的段內地址(偏移量)找到對應的實體地址。

計算機作業系統——虛擬記憶體與實體記憶體

缺點:造成物理出現外部碎片。虛擬地址中相鄰的段對應到實體記憶體中可能就不相鄰了,這樣雖然實現了實體記憶體的離散分配,但是可能造成實體記憶體中相鄰的段之間出現記憶體碎片(不足以對映給虛擬記憶體中的段)。

分頁

將應用程式的虛擬地址空間劃分成連續的,等長的虛擬頁,同時實體記憶體也被劃分為等長的,連續的虛擬頁。作業系統為每一個應用程式構造頁表(虛擬頁到物理頁的對映關係表)。分頁機制下的虛擬地址由兩部分構成:虛擬頁號頁內偏移量

MMU通過應用程式的頁表找到虛擬頁號對應的實體地址,再通過頁內偏移量找到對應的實體地址。

計算機作業系統——虛擬記憶體與實體記憶體

多級頁表

上面的簡單分頁機制在位作業系統中,還能用,但是在64位作業系統中就不行了。64位作業系統,虛擬地址長64位,也就是8個位元組,64位定址範圍是0~2^64,如果一個虛擬頁大小4KB,那麼就會有2^64/4KB個虛擬頁,如果用一張頁表來記錄,一個頁表項8位元組,那麼頁表大小就為2^64/4KB*8,這是一個無法接受的數字。為了壓縮頁表的大小,多級頁表應運而生。下面是一個4級頁表的示意圖:

計算機作業系統——虛擬記憶體與實體記憶體

在多級分頁機制下,0級頁表只有一個頁表頁,而其餘每一級頁表都可以擁有多個離散的頁表頁。虛擬地址可以分為兩部分:虛擬頁號頁內偏移。只不過虛擬頁號可以進一步分為四個部分,依次對應其在對應級數頁表中的索引。當任意一級頁表中的條目為空時,就意味著該條目對應的下一級頁表不需要存在,因此節省了大量空間。