在 Linux 系統中,采用了虛擬內存管理技術,事實上大多數現在操作系統都是如此!在 Linux 系統中,每一個進程都在自己獨立的地址空間中運行,在32 位系統中,每個進程的邏輯地址空間均為 4GB,這 4GB 的內存空間按照 3:1 的比例進行分配,其中用戶進程享有 3G 的空間,而內核獨自享有剩下的1G 空間,如下所示:
虛擬地址會通過硬件MMU(內存管理單元)映射到實際的物理地址空間中,建立虛擬地址到物理地址的映射關系后,對虛擬地址的讀寫操作實際上就是對物理地址的讀寫操作,MMU會將物理地址“翻譯”為對應的物理地址,其關系如下所示:
Linux 系統下,應用程序運行在一個虛擬地址空間中,所以程序中讀寫的內存地址對應也是虛擬地址,并不是真正的物理地址,譬如應用程序中讀寫0x80800000 這個地址,實際上并不對應于硬件的 0x80800000 這個物理地址。
為什么需要引入虛擬地址呢?
計算機物理內存的大小是固定的,就是計算機的實際物理內存,試想一下,如果操作系統沒有虛擬地址機制,所有的應用程序訪問的內存地址就是實際的物理地址,所以要將所有應用程序加載到內存中,但是我們實際的物理內存只有G,所以就會出現一些問題:
當多個程序需要運行時,必須保證這些程序用到的內存總量要小于計算機實際的物理內存的大小。
內存使用效率低。內存空間不足時,就需要將其它程序暫時拷貝到硬盤中,然后將新的程序裝入內存。然而由于大量的數據裝入裝出,內存的使用效率就會非常低。
進程地址空間不隔離。由于程序是直接訪問物理內存的,所以每一個進程都可以修改其它進程的內存數據,甚至修改內核地址空間中的數據,所以有些惡意程序可以隨意修改別的進程,就會造成一些破壞,系統不安全、不穩定。
無法確定程序的鏈接地址。程序運行時,鏈接地址和運行地址必須一致,否則程序無法運行!因為程序代碼加載到內存的地址是由系統隨機分配的,是無法預知的,所以程序的運行地址在編譯程序時是無法確認的。
針對以上的一些問題,就引入了虛擬地址機制。程序訪問存儲器所使用的邏輯地址就是虛擬地址,通過邏輯地址映射到真正的物理內存上。所有應用程序運行在自己的虛擬地址空間中,使得進程的虛擬地址空間和物理地址空間隔離開來,這樣做帶來了很多的優點:
進程與進程、進程與內核相互隔離。一個進程不能讀取或修改另一個進程或內核的內存數據,這是因為每一個進程的虛擬地址空間映射到了不同的物理地址空間。提高了系統的安全性與穩定性。
在某些應用場合下,兩個或者更多進程能夠共享內存。因為每個進程都有自己的映射表,可以讓不同進程的虛擬地址空間映射到相同的物理地址空間中。通常,共享內存可用于實現進程間通信。
便于實現內存保護機制。譬如在多個進程共享內存時,允許每個進程對內存采取不同的保護措施,例如,一個進程可能以只讀方式訪問內存,而另一進程則能夠以可讀可寫的方式訪問。
編譯應用程序時,無需關心鏈接地址。前面提到了,當程序運行時,要求鏈接地址與運行地址一致,在引入了虛擬地址機制后,便無需關心這個問題。
-
Linux
+關注
關注
87文章
11479瀏覽量
213056 -
內存
+關注
關注
8文章
3115瀏覽量
75068 -
地址
+關注
關注
1文章
32瀏覽量
10986 -
系統
+關注
關注
1文章
1029瀏覽量
21742
發布評論請先 登錄
探討一下ARM中的MMU虛擬地址
linux kernel實現物理地址到虛擬地址空間的切換方法
ARM處理器使用虛擬地址來提供cache index和cache tag
鴻蒙內核中虛擬地址與物理地址之間是如何映射的

內核邏輯地址和內核虛擬地址到底有什么區別
虛擬地址和邏輯地址的區別是什么?

虛擬地址物理地址等眾多地址及MMU相關知識

為什么要用MMU?為什么要用虛擬地址?
Linux虛擬地址空間和物理地址空間的關系

Linux虛擬地址到物理地址轉換過程

評論