首頁  >  文章  >  虛擬記憶體是電腦記憶體的一部分嗎?

虛擬記憶體是電腦記憶體的一部分嗎?

青灯夜游
青灯夜游原創
2020-08-19 15:19:146800瀏覽

虛擬記憶體是電腦實體記憶體中劃分出來的一部分。虛擬記憶體是電腦系統記憶體管理的技術,它通常是被分隔成多個實體記憶體碎片,還有部分暫時儲存在外部磁碟記憶體上,在需要時進行資料交換。

虛擬記憶體是電腦記憶體的一部分嗎?

作業系統有虛擬記憶體與實體記憶體的概念。在很久以前,還沒有虛擬記憶體概念的時候,程式尋址用的都是實體位址。程式能定址的範圍是有限的,這取決於CPU的位址線條數。例如在32位元平台下,尋址的範圍是2^32也就是4G。而這是固定的,如果沒有虛擬內存,且每次開啟一個進程都給4G的物理內存,就可能會出現很多問題:

  • 因為我的物理內存時有限的,當有多個進程要執行的時候,都要給4G內存,很顯然你內存小一點,這很快就分配完了,於是沒有得到分配資源的進程就只能等待。當一個進程執行完了以後,再將等待的進程裝入記憶體。這種頻繁的裝入記憶體的操作是很沒效率的

  • 由於指令都是直接存取物理記憶體的,那麼我這個進程就可以修改其他進程的數據,甚至會修改內核位址空間的數據,這是我們不想看到的

  • 因為記憶體時隨機分配的,所以程式運行的位址也是不正確的。

於是針對上面會出現的各種問題,虛擬記憶體就出來了。

一個行程在執行時都會得到4G的虛擬記憶體。這個虛擬記憶體你可以認為,每個進程都認為自己擁有4G的空間,這只是每個進程認為的,但是實際上,在虛擬內存對應的物理內存上,可能只對應的一點點的物理內存,實際用了多少內存,就會對應多少物理內存。

進程得到的這4G虛擬記憶體是一個連續的位址空間(這也只是進程認為),而實際上,它通常是被分隔成多個物理記憶體碎片,還有一部分儲存在外部磁碟在記憶體上,在需要時進行資料交換。

程式開始要存取一個位址,它可能會經歷下面的過程

  • #每次我要存取位址空間上的某一個位址,都需要把位址翻譯為實際物理記憶體位址

  • 所有行程共享這整一塊實體內存,每個行程只把自己目前需要的虛擬位址空間映射到物理記憶體上

  • #進程需要知道哪些位址空間上的資料在實體記憶體上,哪些不在(可能這部分儲存在磁碟上),還有在實體記憶體上的哪裡,這就需要透過頁表來記錄

  • 頁表的每個表格項目分成兩部分,第一部分記錄此頁是否在實體記憶體上,第二部分記錄實體記憶體頁的位址(如果在的話)

  • 當進程存取某個虛擬位址的時候,就會先去看頁表,如果發現對應的資料不在實體記憶體上,就會發生缺頁異常

  • ##缺頁異常的處理過程,作業系統立即阻塞該進程,並將硬碟裡對應的頁換入內存,然後使該進程就緒,如果內存已經滿了,沒有空地方了,那就找一個頁覆蓋,至於具體覆蓋的哪個頁,就需要看作業系統的頁面置換演算法是怎麼設計的了。

關於虛擬記憶體與實體記憶體的聯繫,下面這張圖可以幫助我們鞏固。

虛擬記憶體是電腦記憶體的一部分嗎?

頁表的工作原理如下圖

虛擬記憶體是電腦記憶體的一部分嗎?

  • #我們的cpu想要存取虛擬位址所在的虛擬頁(VP3),根據頁表,找出頁表中第三條的值.判斷有效位。若有效位元為1,DRMA快取命中,根據實體頁號,找到實體頁當中的內容,返回。

  • 若有效位元為0,參數缺頁異常,呼叫核心缺頁異常處理程序。核心透過頁面置換演算法選擇一個頁面作為被覆蓋的頁面,將該頁的內容刷新到磁碟空間當中。然後把VP3映射的磁碟檔案快取到該實體頁上面。然後頁表中第三條,有效位元變成1,第二部分儲存了可以對應實體記憶體頁的位址的內容。

  • 缺頁異常處理完畢後,返回中斷前的指令,重新執行,此時快取命中,執行1。

  • 將找到的內容對應到告訴快取當中,CPU從告訴快取中取得該值,結束。

再來總結虛擬記憶體是怎麼運作的#

當每個進程創建的時候,核心會為進程分配4G的虛擬內存,當進程還沒有開始運行時,這只是一個內存佈局。實際上並沒有立即就把虛擬記憶體對應位置的程式資料和程式碼(例如.text .data段)拷貝到實體記憶體中,只是建立好虛擬記憶體和磁碟檔案之間的映射就好(叫做記憶體對映)。這時候資料和程式碼還是在磁碟上的。當執行到對應的程式時,進程去尋找頁表,發現頁表中位址沒有存放在實體記憶體上,而是在磁碟上,於是發生缺頁異常,於是將磁碟上的資料拷貝到實體記憶體中。

另外在進程運行過程中,要透過malloc來動態分配記憶體時,也只是分配了虛擬內存,即為這塊虛擬內存對應的頁表項做相應設置,當進程真正訪問到此數據時,才引發缺頁異常。

可以認為虛擬空間都被映射到了磁碟空間中(事實上也是按需要映射到磁碟空間上,透過mmap,mmap是用來建立虛擬空間和磁碟空間的映射關係的)

利用虛擬記憶體機制的優點 

  • 既然每個行程的記憶體空間都是一致且固定的(32位元平台下方都是4G),所以連結器在連結可執行檔時,可以設定記憶體位址,而不用去管這些資料最終實際記憶體位址,這交給核心來完成映射關係

  • 當不同的當行程使用同一段程式碼時,例如庫檔案的程式碼,在實體記憶體中可以只儲存一份這樣的程式碼,不同行程只要將自己的虛擬記憶體映射過去就好了,這樣可以節省實體記憶體

  • #在程式需要分配連續空間的時候,只需要在虛擬記憶體分配連續空間,而不需要實體記憶體時連續的,實際上,往往物理記憶體都是斷斷續續的記憶體碎片。這樣就可以有效地利用我們的實體記憶體

更多相關知識,請造訪:PHP中文網

以上是虛擬記憶體是電腦記憶體的一部分嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn