計算機操作系統(復習)--- 虛擬內存


問題

  • 為什么需要虛擬內存
  • 如何實現

虛擬內存的動機

  早期程序員自己寫程序還要自己管理內存地址(內存條上的地址),要自己知道分配到內存條的哪個地方, 為了解決這個問題,早期的分頁管理就出現了,程序員只要知道邏輯地址就可以,然后真實的物理地址不需要管,由分頁管理。   舉例 : 當時有一種計算機,其指令中給出的主存地址為16位,而主存容量只有4k字,則指令可尋址范圍是多少呢?   答 : 2的16次方,當時內存2的16次方遠遠大於4k字這個可用范圍,怎么辦呢?相當於說我的程序非常地長,而我們主存裝不下,於是就出現了分頁加載,分段加載,段頁式加載。個人覺得虛擬內存的原因 :

  • 計算機只能加載部分程序,內部不能像硬盤那樣的容量
  • 內存管理

早期分頁方式執行過程

  • 只有一個頁框,也就是只有一頁可以加載到內存中去
  • 把執行完的程序放回磁盤中去,新的加載進來
  • 改變地址映射(僅改變映射區間(頁號))

現在分頁

  邏輯地址可以無限大,實際是映射在物理地址上的。這里所說的物理地址指的是主存的物理地址!!!!不是磁盤的物理地址!!切記頁表示例.PNG   假如進程A有4張表,位於13 14 15 18 這幾個頁框內(物理地址可以不連續),當此時我需要訪問邏輯中的1號的位置,那么操作系統就會去進程A 頁表中找到1 對應的是哪個主存的哪個位置,經過查詢是 14頁框的地址,里面放着是對應的物理地址,於是就拿到了想要訪問的物理地址。

  • 頁表左邊 : 0123 表示的是邏輯地址上的第一頁,第二頁,第三頁...
  • 頁表右邊 : 表示的是對應的在主存中的哪個頁框,上圖就是主存的14號頁框   也就是說邏輯地址只是一個代號0123456789....,而物理頁框是表示真正在內存中的頁框位置,那么就有可能假如說我要找邏輯地址為9對應的內存頁框是哪個的時候,發現對應的頁框是空的(還沒有加載進來),就是說缺頁了,此時就要從磁盤中加載也到內存中去,有可能頁表對應的物理地址在磁盤中(物理地址 : 主存中,磁盤中,空頁)。

虛擬存儲系統

虛擬存儲系統的基本概念

虛擬內存基本概念.PNG

  這張圖非常重要,虛擬內存解決的問題就是要讓程序員在比主存空間大得多的邏輯地址空間中編寫程序 ,程序的機器碼是放在硬盤中的, 硬盤相對於主存大的很多,所以可以表示的地址大的很多,但是CPU 是在主存中讀取程序的,所以就用了一套邏輯地址來表示運行的數據放在哪個地方,而頁表就是來表示邏輯地址和物理地址之間的映射的,假如物理地址中沒有數據就是缺頁了,那么就從磁盤中先加載到內存中再繼續運行。 

虛擬存儲技術的實質

  • 程序猿可以比在實際主存空間大得多的邏輯地址空間中編寫程序
  • 按需調用程序 虛擬存儲技術的實質.PNG

執行程序 -》 啟動進程 -》 調程序到主存中

虛擬地址空間

  虛擬地址把內核空間和用戶空間一分為二,執行用戶空間里的代碼后又轉向執行內核空間的代碼,就會發生 進程的上下文切換 。 下面的是用戶棧和堆則是向着一個方向生長着,中間有個 Memory-mapped region for shared libraries  ,

  一個進程的虛擬地址空間包括內核虛擬內存和用戶棧等等。  

    可執行文件初始化的時候只會建立頁表不會馬上就加載到內存中去,只有需要的時候才進行加載,所以才會產生缺頁。 虛擬地址.PNG

 

 

虛擬存儲器管理的實現要解決的問題

  也就是解決以下問題 :

 

問題.PNG

 

主存-磁盤層次 

 

  這里的 write back 就是java 的 flush 一樣的操作,因為 CPU 不可能寫內存頁的一點內容然后馬上就回刷回去,肯定是寫內存,然后在某個時間點在flush 回去,那么就必須有個標志來表示臟頁。  

 

頁表

 

  • 裝入位 : 表示該頁存不存在內存中(是否已經從磁盤中加載進來了)
  • 修改位 : 上面所說的,該內存頁是否給人修改了,即是否是臟頁
  • 替換位 : 內存空間不大,所以要用 cache 算法來交換替代那些暫時不需要的內存頁。
  • 訪問位 : 
  • 禁止緩存位  :  這個要是給其他用的,給不給緩存到cache 里面去
  • 實頁為 :  該邏輯地址對應的是內存中的哪一頁,頁框編號,因為每一頁的大小都是一樣的,那么就相當對內存除以頁的大小,就可以算出主存到底可以放多少個頁,對每一個頁的位置進行編號,就是頁框號

  一個進程,邏輯地址共 4GB , 一頁為 4KB ,所以需要用 2 的 20 次方這么多頁來表示一個進程的頁表,所以一個進程的頁表項數太多了(HashMap 的 size 同理) ,所以對頁表也要分頁。 頁表是放在虛擬空間的內核地址里面。

 

頁項分類

  頁表中(相當於一個HashMap , key 是邏輯地址,value 邏輯地址對應的信息) 這么多項可以分類為三種

  • 未分配頁 :未使用
  • 已分配的緩存頁 : 快要被執行了,磁盤里的數據已經加載到主存中了!!!所以CPU 只要這個地址就夠了(假如CPU 此時 read 操作,write 也可以啊,改了數據后再 write back 回刷回硬盤)
  • 已分配的未緩存頁  : 該頁快給使用到了,但是內容還在磁盤中還未加載進來。 

頁表的緩存

  我們上面說了一個進程的頁表要有2的20次方項,這太大了,所以我們要對頁表進行緩存,把經常用的頁表的中的項緩存起來,這個東西就是  TLB 。 這里說一下全相聯和組相聯,全相聯相當於給了某一個HashMap 中的某一個 key 的值,那么就很准確得到 value , 而組相聯則是先給你某一個HashMap ,再給你一個 index ,就是從這個HashMap 從 0 開始數,往下找。 

 

CPU 訪問示例 

  

  我們看到假如CPU 首先查看 TLS 中有已經緩存的頁表項,那么直接到 CaChe 中的拿就好了,走Hit 3 那條路線返回,這是最好的結果,根本不用訪問內存,下面這張圖要好好理解 。 

補充


clipboard.png   上圖是存儲層次圖。

總結

  文章對虛擬內存進行復習,后面幾篇文章細講分頁式和分段式的實現。

參考文章

  • mooc上袁春風老師的課


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM