虛擬儲存器

2021-08-22 11:57:30 字數 2806 閱讀 4456

今天上午看了《深入理解計算機系統》中關於虛擬儲存器的章節,記錄如下:

首先說為什麼要有虛擬儲存器

我個人覺得虛擬儲存器的概念是和程序概念一起出現的。在計算機技術發展的早期,只有單道批處理系統,特點是一次只能執行乙個程序,只有執行完畢後才能將下乙個程序載入到記憶體裡面,所以程序的資料都是直接放在物理記憶體上的。

到後來發展出了多道程式系統,它要求在計算機中存在著多個程序,處理器需要在多個程序間進行切換。這時候就出現問題了,鏈結器在鏈結乙個可執行檔案的時候,總是預設程式的起始位址為0x0,但物理記憶體上只有乙個0x0的位址呀?也許你會說:」沒關係,我們可以在程式裝入記憶體的時候再次動態改變它的位址.」好吧我忍了。但如果我的物理記憶體大小只有1g,而現在某乙個程式需要超過1g的空間怎麼辦呢?你還能用剛才那句話解釋嗎?

這時候虛擬儲存器的作用就發揮出來了,我們為每乙個程序分配乙個0~232-1個位元組(32為系統,下同)的虛擬位址空間,並將這些空間在邏輯上分為各個段,每個段的作用、位置和訪問許可權都不同,具體可見我的關於程序這篇文章

。使用虛擬儲存器有如下好處:

虛擬儲存器的工作原理

當作業系統將乙個程式載入記憶體時,會為其建立乙個pcb出來,pcb在linux系統中就是乙個task_struct的核心結構體,其中的元素包含或者指向核心執行該程序所需要的所有資訊(例如:pid,指向使用者棧的指標,可執行目標檔案的名稱以及程式計數器)。

task_struct中有乙個條目mm指向mm_struct,它描述了虛擬儲存器的當前狀態。我們感興趣的兩個欄位是pgd和mmap,其中pgd指向一級頁表的基址,而mmap指向乙個vm_area_structs的鍊錶,其中每個vm_area_structs都描述了虛擬位址空間的乙個區域,也就是我上文所說的「段」。示意圖如下:

由上圖可知,vm_area_struct結構體中各欄位含義如下:

值得說明的是,上圖中的使用者棧由兩個暫存器ebp和esp維護,堆由程式設計師自己維護,所以沒有vm_area_struct結構體指向它(個人認為,有待證實)。

以上資料結構建立好後,程序就可以載入執行了。當然,此時物理記憶體上還沒有任何該程序的資料資訊。當cpu要訪問某乙個位址時,發現該頁面並沒有存在於物理記憶體上,就產生乙個缺頁中斷(關於頁表和缺頁中斷在下文表述),此時在中斷處理程式內,作業系統會開闢一塊記憶體出來並將外存上的資料存放進來,然後退出中斷處理程式,cpu重新執行剛剛產生中斷的那句指令,此時就不會再次導致缺頁了。

以上就是虛擬儲存器的工作原理。由此可見,根據程式執行的區域性性原理,使用虛擬儲存器只將程序中用到的資料載入進物理記憶體,可以大大提高記憶體的使用率。

頁表和位址翻譯

既然有了虛擬位址,我們就需要有一種方法將虛擬位址和物理位址對映起來,這是通過頁表來實現的。頁表也是儲存在物理記憶體中的資料,只不過它由核心維護。頁表中記錄了乙個虛擬位址是否已經被對映到物理記憶體上的某個位置,如已經對映,還記錄了具體的物理記憶體位址。由於訪問頁表相當於多了一次記憶體訪問,因此有的計算機系統將頁表快取到mmu(memory manage unit,記憶體管理單元)中的頁表快取中,稱作tlb(translation lookaside buffer,翻譯後備緩衝器)。當然,這不是我們要討論的內容。

當cpu需要訪問乙個虛擬位址時,首先用這個虛擬位址根據某乙個hash演算法去查詢對應的頁表,這個操作的時間複雜度為o(1).若發現該虛擬位址已經被對映到物理記憶體上,則根據頁表中給出的實體地址再去物理記憶體上查詢即可。接下來我們討論的是虛擬位址沒有被對映到物理記憶體的情況,即缺頁。

發生缺頁時,作業系統觸發乙個缺頁異常,執行以下處理動作:

若頁表中還有空餘空間,則分配乙個出來,同時分配一塊物理記憶體出來,將所需的資料從磁碟拷貝到這裡並更新頁表。

若頁表已滿,則根據某種頁面排程演算法選擇乙個犧牲頁,在採用「寫一次法」的系統中,若該犧牲頁已經被修改,則將它同步回磁碟。然後再從磁碟將資料拷貝到一塊新分配的物理記憶體中並更新頁表。

退出異常處理程式時,cpu重新執行剛才導致缺頁中斷的那條指令。

有了以上關於頁表的基礎,我們在來看看以前學習的一些知識。

再看fork函式

fork函式的作用是建立乙個子程序出來。其需要執行的動作有:

因此可以看出,建立乙個子程序的開銷是很大的。現代作業系統採用了一種寫時拷貝的技術(cow,copy on write),即只是拷貝子程序的頁表,並沒有為其分配實際物理記憶體,也就是父子程序共同使用相同的物理記憶體。但會把這塊記憶體的vm_area_struct結構體中的vm_prot欄位標記為唯讀的。當父子程序都讀取這些記憶體中資料時沒有問題,如果某乙個程序往裡面寫資料,才開始為其分配實際物理記憶體,並將資料拷貝過去,將他們標記為可寫的,然後再寫入資料。

再看exec函式

exec是乙個函式族,完成的功能是程式替換。需要以下幾個步驟:

如上就是exec函式所做的工作,隨後linux將根據需要換入**和資料頁面。

再看共享記憶體機制

linux程序間通訊機制中有一種方式是共享記憶體,其機理是使兩個程序的頁表指向同一塊物理記憶體,這樣兩個程序就可以通過頁表訪問同一塊記憶體了。

再看malloc函式

malloc和free是c標準庫的庫函式,用來在堆上分配和釋放空間。malloc管理著乙個空閒鍊錶,這個空閒鍊錶記錄著堆空間上所有未被使用的空間,每次呼叫malloc函式時,就從該鍊錶上找出一塊足夠大的空間返回給呼叫者並將其從空閒鍊錶上刪除。如果找不到足夠大的空間,malloc就呼叫sbrk函式來增大brk變數,以增大堆空間。brk是核心為每個程序所維護的乙個變數,記錄著堆的邊界。

free函式則與malloc相反,它直接將所分配的記憶體新增到空閒鍊錶當中即可。但要注意的是,free函式必須要檢查所釋放的空間是否是由malloc/calloc/realloc函式分配的,如果不是,則觸發乙個異常。

虛擬儲存器

1 虛擬儲存器只是乙個容量非常大的儲存器的邏輯模型,不是任何實際的物理儲存器 2 它借助於磁碟等輔存來擴大主存的容量,使之為更大或更多的程式使用 3 程式的邏輯位址稱為虛擬位址 虛位址 程式的邏輯位址空間稱為虛擬位址空間 4 實體地址 實位址 由cpu位址引腳送出,是用於訪問主存的位址 5 設cpu...

虛擬儲存器

在系統中程序是與其它的程序共享cpu和主存資源的,程序太多就需要太多的儲存器,而且儲存器很容易受到破壞,如果某個程序不小心寫了另乙個程序使用的儲存器,它就會以 完全和程式邏輯無關的令人迷惑的方式失敗。位址空間。特點 1.主存看成是虛擬在磁碟上的位址空間 的快取記憶體,在主存裡只儲存活動區域。2.為每...

虛擬儲存器

1 常規儲存器管理方式的特徵 一次性 即作業在執行前需一次性地全部裝入記憶體。這會導致兩種情況的發生 當作業很大,所要求的記憶體空間超過了記憶體總容量,作業不能全部被裝入記憶體,致使該作業無法執行。在多道程式中,有多個作業要求執行,但由於記憶體容量不足以容納所有這些作業,只能將少數作業裝入記憶體讓它...