直觀地想,當邏輯地址比物理地址少時就不會存在衝突問題,更不需要多級頁表機制了,為什麼邏輯地址要設計的比物理地址多呢?


其實完全沒有必要更多。其實是你想反了。不是邏輯地址更多,而是物理地址更少。

為啥物理地址比邏輯地址更少呢?因為大家買不起那麼多物理內存啊。


有mmu這個東西,可以分配虛擬地址(題中邏輯地址,下同),再加上內核的支持,可以提升物理內存的利用率。

講一下Linux Kernel的處理,當運行一個程序時,內核並不會把整個程序完全載入到物理內存中,而是分配好虛擬地址,載入可執行文件的部分到物理內存,只分配了虛擬地址而程序未載入到物理內存的部分,會在頁表上做標記。

當程序運行到只有虛擬地址而沒有對應物理內存的地方時,處理器會發生異常,然後內核就分配對應的物理內存頁,把磁碟上的數據載入到物理內存,再從異常中返回,程序就能繼續運行。這個過程,用戶態的程序是無法感知到的。

這樣,就算分配的虛擬地址大於實際的分配的物理內存也是沒有問題的。通過這種機制,假設我有一個遠大於物理內存的程序,也是能運行的。在系統物理內存用光的情況下,當程序運行到新的地方,而這部分只分配了虛擬地址,沒有對應物理內存時,內核在缺頁異常中搜索最不常執行的地方,斷開物理內存與原來虛擬地址的連接,把這塊物理內存分配給當前程序將要運行的新的虛擬地址,然後把磁碟上的程序載入到物理內存,這樣程序又能快樂的運行了。

綜上,虛擬地址會比物理地址多,而且也是有必要。計算機里有一個重要的情況,基本上很多東西都是局部的,一個程序雖大(比如我們的假設,磁碟上的程序遠大於物理內存),但經常執行的地方卻不多。cache也是根據這個情況設計出來的,雖然可能只有幾十兆,但是性能提升非常高。

上面說了單進程的情況,下面說說多進程的情況。多進程時,活躍的進程可能就那麼幾個,其他基本上在睡大覺。32位機上,每個進程都分了4g虛擬地址空間,但是真正需要全部把程序載入到物理內存的不多,或者,我一個程序原來用了很多內存,但後面不怎麼運行,內核在內存緊張時,會把這部分物理內存釋放掉,分配給其他用途。

前面說的是程序部分,現在說說數據部分,或者說是堆內存這塊(malloc分配的)。如果這部分內存不常使用,內核會把他們丟入交換空間(swap,位於磁碟上)這個冷宮。等到真正需要時,才把數據從交換空間拿到物理內存。

綜上,這幾種情形,使用了虛擬地址,可以讓物理內存可以使用得更高效。邏輯地址比物理地址多不言而喻了吧。

ps:我深入到細節的這種講述不知道好不好理解,文字又比較多。


那假如你機器物理內存2G,開機操作系統佔用1G多,剩下幾百兆內存,你覺得還能幹啥?


邏輯地址比物理地址少的時候也不代表就不會存在衝突了啊.你要知道每個進程都是擁有獨立的虛擬地址空間的,而且理論上進程數量是無限的,你就算一個進程的邏輯地址空間設的再小,多個進程對應的還是那一個物理地址空間,怎麼分?

再說多級頁表機制也不是為了防止衝突的,而是因為虛擬地址空間太大了,如果用一級頁表,光頁表就可能幾百兆,這還是一個進程的,多個進程就更別說了.


你提的問題本身就有問題,本末倒置了。先好好學學操作系統的存儲管理機制,段式,頁式,段頁式是怎麼回事。你那不是直觀的想,是臆想。


highmem了解一下。如果邏輯地址比物理地址多,只會增加更多複雜度。這就是普及64位機器和操作系統的重要原因之一


反正是虛擬的,為啥不大點呢,萬一哪天改需求。


讓程序覺得內存夠用,使命載入數據進來讓CPU滿負荷運轉,充分利用處理機。


就跟賬本和現金流的關係一樣,賬上錢大手大腳轉來轉去,前面剛還了後面又借了,真是大方,可真正死到臨頭了得看現金流


線性地址空間大-&>程序寫起來爽

物理地址空間小-&>窮

而且,即使線性地址空間小於物理地址空間,也沒有辦法避免地址衝突。為了實現地址獨立,引入了分段和分頁等機制,和地址空間的相對大小沒有關係


推薦閱讀:
相关文章