您當前的位置:首頁 > 動漫

談一談記憶體管理,虛擬記憶體,多級頁表

作者:由 Kyrie 發表于 動漫時間:2021-03-16

在說虛擬記憶體之前,我們先搞清楚下啥是記憶體。

記憶體

記憶體是計算機中重要的部件之一,它是外存(硬碟等)與CPU進行溝通的橋樑。計算機中所有程式的執行都是在記憶體中進行的,因此記憶體的效能對計算機的影響非常大。去淘寶上搜搜記憶體條,那就是計算機中的記憶體硬體。

談一談記憶體管理,虛擬記憶體,多級頁表

物理地址

記憶體上原始的地址就是物理地址,在x86的32位機子上,最大能支援的物理記憶體是4GB,它的物理地址就是從[00000000,ffffffff]。

虛擬地址

虛擬地址是物理記憶體的一個對映,可能虛擬地址00000000對應f0000000,也有可能對應00001000。這主要是為了讓每一個程序都擁有相同的地址空間。相當於每個程序都獨佔CPU,都假設自己用來4GB的物理記憶體。這樣的好處在於寫程式碼時可以從繁瑣的記憶體管理中抽身出來,不用在意當前地址是否被其他程序所佔用,因為作業系統會自動將其對映到未使用的物理記憶體上。也讓程式具有了移植性。

談一談記憶體管理,虛擬記憶體,多級頁表

有了虛擬地址,我們就可以對其對映方法進行設計,從而實現對物理記憶體的記憶體管理。

虛擬地址怎麼對應到具體的物理地址上呢?

記憶體管理 + 分頁!

將物理記憶體分成一頁一頁(也可以說一塊一塊,但塊是在檔案系統的一個名詞),每頁的大小固定,通常是4KB一頁。4GB的記憶體就會被分成1024*1024 = 1048576個頁。

談一談記憶體管理,虛擬記憶體,多級頁表

怎麼記錄還有哪些頁沒被使用,怎麼使用這些物理頁?

從物理記憶體中取一些記憶體用來做

struct pageInfo

陣列的存放地址。一共1048576個頁,那麼就需要1048576個

pageInfo

。那怎麼知道每個

pageInfo

對應哪個物理頁呢?在核心程式中用

pageInfo[i]

的下標i就可以啦。這相當於物理頁的代言人。

談一談記憶體管理,虛擬記憶體,多級頁表

怎麼對這些頁進行管理呢,比如標記被使用,許可權等?

4KB一頁就意為著每個頁的起始地址最後三位一定是000,4KB = 0x00001000。所以相當於空出了12位,所以可以利用這些位來做頁內偏移。前22位就是用來尋找頁面,這個由專門的頁表進行管理。

虛擬地址的轉換:透過查詢頁表找到頁(找到頁的代言人PageInfo),再使用頁內偏移找到最終的物理地址,頁表的結構有哪些呢?

一級頁表:

物理記憶體中一共有1048576個頁,那麼頁表就需要總共就是1048576 * 4B = 4M。也就是說我需要4M連續的記憶體來存放這個頁表,也就是一級頁表。隨著虛擬地址空間的增大,存放頁表所需要的連續空間也會增大,在作業系統記憶體緊張或者記憶體碎片較多時,這無疑會帶來額外的開銷。

談一談記憶體管理,虛擬記憶體,多級頁表

為什麼會出現多級頁表呢?

一級頁表:管理1048576個頁的表,每個頁分配4B記憶體來管理,所以總共需要1024 x 1024 x 4 x 8 = 4MB的記憶體來儲存這個表。我們物理記憶體是以4KB為單位頁,所以存一個一級頁表就需要1024個頁來存,而且還必須是連續的頁!

根據一級頁表機制的缺點,

多級頁表的出現肯定是可以節約記憶體的

。使用二級頁表的話,我們就可以對這個4MB的表進行

二次分頁。最終用一個4K的記憶體,即一頁就可以管理全部的物理記憶體。

只需要載入一個頁目錄表,大小為4K,可以管理1024個二級頁表。可能你會有疑問,這1024個二級頁表也是需要記憶體空間的,這下反而需要4MB+4KB的記憶體,反而更多了。 我們可以對定址的地址動手腳,將其分成3塊,dir pageIndex offset。其中dir需要10位,用來在頁目錄中偏移, pageIndex也是10位,在頁表中偏移, offset 是

12

位在具體的物理頁中偏移

物理頁是由4K個Byte組成。需要精確的訪問到每個Byte。而頁表,頁目錄可以用 4 * addr訪問對應的4B。

換句話說物理頁項單位是B,頁表項和頁目錄項單位是4B

談一談記憶體管理,虛擬記憶體,多級頁表

談一談記憶體管理,虛擬記憶體,多級頁表

標簽: 記憶體  頁表  物理  虛擬地址  1024