電腦作業系統——虛擬記憶體與物理記憶體

虛擬記憶體與物理記憶體

如何管理記憶體?

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

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