"點我查看秘籍連載" 分頁和頁表 除了分段,空間管理的第二種常見方式是分頁。 Linux將虛擬記憶體劃分成固定大小的頁(Linux中的頁大小是4KB),並且以頁作為操作記憶體的最小單元。例如一次性讀取一頁,虛擬記憶體中的頁稱為虛擬頁。對應的,物理記憶體也會劃分成固定大小的頁來管理,稱為物理頁,也常稱為 頁框 ...
分頁和頁表
除了分段,空間管理的第二種常見方式是分頁。
Linux將虛擬記憶體劃分成固定大小的頁(Linux中的頁大小是4KB),並且以頁作為操作記憶體的最小單元。例如一次性讀取一頁,虛擬記憶體中的頁稱為虛擬頁。對應的,物理記憶體也會劃分成固定大小的頁來管理,稱為物理頁,也常稱為頁框或頁幀(page frame)。物理頁和虛擬頁的大小相等。
值得註意的是,雖然虛擬記憶體和物理記憶體都將空間全部劃分成頁,但不可能會為所有虛擬頁分配好所有對應的物理頁,所以虛擬頁有一個有效位的屬性,如果該頁有分配對應的物理頁,則有效,否則無效。
為了將虛擬頁的頁號(Virtual page number,VPN)和物理頁的頁號(Physical page number, PPN)也對應起來,也需要進行地址翻譯。如圖所示。
為了完成這個翻譯過程,操作系統為每個進程都維護了一個稱為頁表(page table)的數據結構。頁表中的每項代表一個頁的映射信息,也稱為頁表項(Page Table Entry,PTE)。
註意,頁表是每個進程都有一個的,因為每個進程的虛擬地址空間都是獨立的,各進程中的頁映射到物理頁自然也是不同的。
每一個頁表項中都保存了很多東西,比如最基本的虛擬頁號和物理頁號、頁偏移、頁是否有效的有效位(比如表明是否已分配該頁記憶體)、頁是否可讀/寫/執行的保護位、頁是存在於記憶體還是存在於交換分區的存在位、頁是否修改過的臟位、頁是否最近訪問過的訪問位,等等。
通過分段+分頁的方式,不再為整個地址空間分配一個頁表,而是為每個段落分配一個頁表,這樣每個頁表的大小就減小了,而且段落是獨立管理的,那麼每個段落中的頁表的訪問頻繁度也將不一樣。在文件系統中,分段+分頁的思想體現為塊組+數據塊。但是分段+分頁的方式也是有缺點的,它雖然為每個段劃分頁表,但仍然為所有的記憶體劃分了頁,且總頁表大小並沒有改變。所以,操作系統不使用這種方案。
第二種方案是使用多級頁表,也是Linux中使用的方案,它不依賴於分段。它的思想是:如果某頁表中包含的所有頁表項都是無效的頁(例如未分配的),就不為這段空間的頁維護頁表,這樣就能減小頁表的大小。這個邏輯其實很簡單:對於沒有分配的頁,沒有必要去記錄這些頁的翻譯方式。
由於不是所有頁都維護了頁表,所以使用一個稱為頁目錄(Page Director)的數據結構去記錄所有的頁表(通過指向頁表的指針記錄),並標記每個頁表是否有效,頁表有效表示該頁表已經分配,這也意味著該頁表中一定有正在使用中的有效頁。因為頁目錄是頁表的更高一層次,所以稱為多級頁表。
下圖顯示了使用線性頁表和多級頁表的不同之處。線上性頁表中,儘管有連續的頁是無效頁,但仍然維護了4個頁表。而在多級頁表中,沒有為那些連續無效的頁維護頁表。顯然,使用多級頁表減小了頁表的大小。