物理內存低於4g如何內存管理(使用分頁機制):

每個進程都擁有4G(2的32次方)的虛擬地址空間。在實際編程過程中,指針中存放的地址也都是32位的線性地址(虛擬地址),經過頁目錄、頁表等分頁機制變換以後可以得到真正的物理地址,而這個物理地址也是32位的。對於32位的CPU來說沒有任何問題,因爲它的地址總線是32位的,尋址空間也就是2的32次方(4G)。那麼問題就出來了:CPU的尋址空間是2的32次方(4G),程序要訪問的物理地址(線性地址經過分頁機制變換以後得到地址)也是32位的,這種情況下的內存應該至少是4G纔對,而平時我們自己用的計算機才一兩個G(比如說就1個G),那麼這時候的內存是怎麼編址的呢(1G內存只要30根地址線就夠了,相應的的物理地址位數只要30位就行了,用不了32位啊)?

的確1G的物理內存虛擬出4G的虛擬內存,進程在使用內存時額外的3G空間是哪來的呀?這時內存分頁機制就發揮它的功效了。

我們知道在內核空間kmalloc函數和__get_free_page函數使用的地址範圍(虛擬地址)和物理內存的地址範圍是一一對應的。兩者只是相差一個偏移(offset)。這是一種線性地址。若我們用vmalloc函數則不然,它所分配的物理內存在地址上是不連續,對於這些不連續地址的管理linux hacker通過創建struct page數據結構來實現。也就是我們所說的頁表。

ps:在ARM處理器中32位的線性地址被分爲3段:

  [31:22]存放頁目錄項地址,即存放要尋址的內存在 頁目錄表 的第幾項,頁目錄表中的每項稱爲頁目錄項,也目錄項中存放的是頁表的地址(指物理地址)  
  [21:12]存放頁表項地址,即內存在 頁表 的第幾項,頁表的每項稱爲頁表項,頁表項存放的是該頁的物理地址
  [11:0]存放頁內偏移地址,通過該值就可以在上面所述的頁中找到內存

頁目錄表地址存放在CP15協處理器中。

而線性地址空間與物理地址空間大小不一致,這才導致產生了分頁機制。
當需要使用不在物理內存中的頁面時,會產生請求調頁,然後操作系統負責內存頁的換入換出。當線性地址轉換到物理地址,而物理地址不足4G(比如1G),操作系統可以給你分配內存。你在線性地址空間得到了需要的內存,而物理內存上通過換頁機制也可以滿足。(假如你想使用3G開始的1頁地址空間,操作系統會把任意空閒的1頁內存給你使用)若真正意義上的內存只有1G。4G到1G,必須得借用硬盤空間。而一個線性地址對應一個物理地址。一個物理地址可能對應好幾個線性地址。但是,使用中的那個會被放在內存,不使用的放在硬盤。由於程序的所謂“局部性”原理,一般這樣做不會有問題。當同時使用內存需求大於1G時,機器就會“很卡”,因爲操作系統不斷地在換入換出內存頁。

參考:

淺談LINUX 內存分頁機制(by liukun321咕唧咕唧)

淺談進程地址空間與虛擬存儲空間

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章