作業系統有虛擬記憶體與物理記憶體的概念。在很久以前,還沒有虛擬記憶體概念的時候,程式定址用的都是實體地址。程式能定址的範圍是有限的,這取決於cpu的位址線條數。比如在32位平台下,定址的範圍是2^32也就是4g。並且這是固定的,如果沒有虛擬記憶體,且每次開啟乙個程序都給4g的物理記憶體,就可能會出現很多問題:
於是針對上面會出現的各種問題,虛擬記憶體就出來了。
在之前一篇文章中程序分配資源介紹過乙個程序執行時都會得到4g的虛擬記憶體。這個虛擬記憶體你可以認為,每個程序都認為自己擁有4g的空間,這只是每個程序認為的,但是實際上,在虛擬記憶體對應的物理記憶體上,可能只對應的一點點的物理記憶體,實際用了多少記憶體,就會對應多少物理記憶體。
程序得到的這4g虛擬記憶體是乙個連續的位址空間(這也只是程序認為),而實際上,它通常是被分隔成多個物理記憶體碎片,還有一部分儲存在外部磁碟儲存器上,在需要時進行資料交換。
程序開始要訪問乙個位址,它可能會經歷下面的過程
每次我要訪問位址空間上的某乙個位址,都需要把位址翻譯為實際物理記憶體位址
所有程序共享這整一塊物理記憶體,每個程序只把自己目前需要的虛擬位址空間對映到物理記憶體上
程序需要知道哪些位址空間上的資料在物理記憶體上,哪些不在(可能這部分儲存在磁碟上),還有在物理記憶體上的**,這就需要通過頁表來記錄
頁表的每乙個表項分兩部分,第一部分記錄此頁是否在物理記憶體上,第二部分記錄物理記憶體頁的位址(如果在的話)
當程序訪問某個虛擬位址的時候,就會先去看頁表,如果發現對應的資料不在物理記憶體上,就會發生缺頁異常
缺頁異常的處理過程,作業系統立即阻塞該程序,並將硬碟裡對應的頁換入記憶體,然後使該程序就緒,如果記憶體已經滿了,沒有空地方了,那就找乙個頁覆蓋,至於具體覆蓋的哪個頁,就需要看作業系統的頁面置換演算法是怎麼設計的了。
關於虛擬記憶體與物理記憶體的聯絡,下面這張圖可以幫助我們鞏固。
我們的cpu想訪問虛擬位址所在的虛擬頁(vp3),根據頁表,找出頁表中第三條的值.判斷有效位。 如果有效位為1,drma快取命中,根據物理頁號,找到物理頁當中的內容,返回。若有效位為0,引數缺頁異常,呼叫核心缺頁異常處理程式。核心通過頁面置換演算法選擇乙個頁面作為被覆蓋的頁面,將該頁的內容重新整理到磁碟空間當中。然後把vp3對映的磁碟檔案快取到該物理頁上面。然後頁表中第三條,有效位變成1,第二部分儲存上了可以對應物理記憶體頁的位址的內容。
缺頁異常處理完畢後,返回中斷前的指令,重新執行,此時快取命中,執行1。
將找到的內容對映到告訴快取當中,cpu從告訴快取中獲取該值,結束。
當每個程序建立的時候,核心會為程序分配4g的虛擬記憶體,當程序還沒有開始執行時,這只是乙個記憶體布局。實際上並不立即就把虛擬記憶體對應位置的程式資料和**(比如.text .data段)拷貝到物理記憶體中,只是建立好虛擬記憶體和磁碟檔案之間的對映就好(叫做儲存器對映)。這個時候資料和**還是在磁碟上的。當執行到對應的程式時,程序去尋找頁表,發現頁表中位址沒有存放在物理記憶體上,而是在磁碟上,於是發生缺頁異常,於是將磁碟上的資料拷貝到物理記憶體中。
另外在程序執行過程中,要通過malloc來動態分配記憶體時,也只是分配了虛擬記憶體,即為這塊虛擬記憶體對應的頁表項做相應設定,當進**正訪問到此資料時,才引發缺頁異常。
可以認為虛擬空間都被對映到了磁碟空間中(事實上也是按需要對映到磁碟空間上,通過mmap,mmap是用來建立虛擬空間和磁碟空間的對映關係的)
當不同的程序使用同一段**時,比如庫檔案的**,在物理記憶體中可以只儲存乙份這樣的**,不同程序只要將自己的虛擬記憶體對映過去就好了,這樣可以節省物理記憶體
在程式需要分配連續空間的時候,只需要在虛擬記憶體分配連續空間,而不需要物理記憶體時連續的,實際上,往往物理記憶體都是斷斷續續的記憶體碎片。這樣就可以有效地利用我們的物理記憶體
物理記憶體與虛擬記憶體區別與聯絡
前一段時間在面試總監的時候,總監問了我這樣的乙個問題 你個我說說物理記憶體和虛擬記憶體到底是怎麼一回事?其實之前我看過這個問題,據我理解的,當時是這麼回答的 程序在執行的時候,作業系統都為其分配乙個4gb的位址空間,即所謂的虛擬位址空間,一般情況下,當我們的程式很大的時候,實際的物理記憶體根本不能滿...
虛擬記憶體與物理記憶體的聯絡與區別
參考部落格原址 作業系統有虛擬記憶體與物理記憶體的概念。在很久以前,還沒有虛擬記憶體概念的時候,程式定址用的都是實體地址。程式能定址的範圍是有限的,這取決於cpu的位址線條數。比如在32位平台下,定址的範圍是2 32也就是4g。並且這是固定的,如果沒有虛擬記憶體,且每次開啟乙個程序都給4g的物理記憶...
虛擬記憶體與物理記憶體的聯絡與區別
作業系統有虛擬記憶體與物理記憶體的概念。在很久以前,還沒有虛擬記憶體概念的時候,程式定址用的都是實體地址。程式能定址的範圍是有限的,這取決於cpu的位址線條數。比如在32位平台下,定址的範圍是2 32也就是4g。並且這是固定的,如果沒有虛擬記憶體,且每次開啟乙個程序都給4g的物理記憶體,就可能會出現...