虛擬存儲器

如果沒有虛擬存儲器,可能會帶來這些問題:
1.所有的進程都共享CPU和主存資源。所以當進程太多,太大,而導致內存無法容納時,就無法運行該進程。
2.存儲器很容易被破壞,當一個程序不小心寫了另外一個進程使用的存儲器時,那麼進程可能就會以一種奇怪的方式而終止。
爲了更加有效的管理存儲器且少出錯,就出現了虛擬存儲器。虛擬存儲器爲每個進程都提供了一個大的,一致的,私有的地址空間
虛擬存儲器:將內存看成是一個存儲在磁盤上的地址空間的高速緩存,在主存中只保存活動區域,並根據需求在磁盤和主存之間來回傳送數據,通過這種方式,高效的使用了主存;爲每一個進程提供了一致的地址空間,簡化了存儲器的管理;保護了每個進程的地址空間不被其他進程破壞。
物理地址和虛擬尋址
計算機系統的主存被組織成爲一個由M個連續的字節大小的單元組成的數組。每個字節都有一個唯一的物理地址。
這裏寫圖片描述
例如上圖:根據虛擬地址,CPU通過生成一個虛擬地址來訪問主存,這個虛擬地址被送到存儲器之前先轉化成適當的物理地址。然後內存讀取地址並返回給CPU。

1.虛擬存儲器作爲緩存的工具

從概念而言,虛擬存儲器被組織爲放在磁盤上的N個連續的字節大小的單元組成的數組。每個字節都有一個唯一的虛擬地址,這個唯一的虛擬地址是作爲到數組的索引的。磁盤上數組的內容被緩存在內存中。
頁表(是一個數據結構):將虛擬頁映射到物理頁。每次地址翻譯硬件將一個虛擬地址轉換爲物理地址時,都會讀取頁表。操作系統負責維護頁表的內容,以及在磁盤與內存之間來回傳送頁。
這裏寫圖片描述
如上圖展示了一個頁表的基本組織結構。我們看到,頁表就是一個數組。頁表中的每一項都是由一個有效位和一個n位字段組成的。有效位表明了該虛擬頁當前是否被緩存在物理存儲器中。如果設置了有效位,那麼有效位後面的地址字段就表示物理存儲器中相應的物理頁的位置,那麼那個相應的物理頁也存儲了該虛擬頁(例如圖中紅色的線段)。如果沒有設置有效位,那麼表示有一個空地址還沒有被分配(例如圖中表述null的地方)。否則,這個地址就指向磁盤上的虛擬頁的起始位置(例如圖中的藍色線段)。
缺頁:在物理內存中找不到的稱爲缺頁。結合上面的圖片,例如,當CPU需要VP3時,發現物理存儲器中沒有。此時,地址翻譯就會從頁表中發現VP3的有效位爲0,那麼就會觸發一個缺頁異常。缺頁異常會調用內核中的相關的處理程序,該程序會在物理存儲器中選擇一個犧牲頁,或許就會把VP4給犧牲掉換爲VP3(這兒涉及到了調度算法),VP4就會重新回到磁盤中,而VP3也就存在了物理存儲器中。當異常處理的程序返回時,它會重新啓動之前的指令,該指令就會把虛擬地址重新發送到地址翻譯硬件中。可是,此時VP3已經存在物理存儲器中了。
但是,當其中缺頁的調度算法不合理時,存儲器就可能在不停的將頁面進行換進換出,那麼就會出現抖動(顛簸)的現象。
缺頁的調度算法的介紹:
1.最佳置換算法.
缺點:缺頁率低;優點:在實際操作中該算法無法實現.所以可以用它來衡量其他算法.
下面模擬實現置換的過程:
這裏寫圖片描述
2.先進先出頁面置換算法.(FIFO)
缺點:缺頁率高;優點:算法簡單,容易實現.
模擬實現:
這裏寫圖片描述
3.最近最久未使用算法.(Least Recently Used)
缺點:對計算機的硬件要求比較高;優點:接近最佳算法.
模擬算法實現:
這裏寫圖片描述

2.虛擬存儲器作爲存儲器管理的工具

在操作系統中,爲每個頁表都提供了一個單獨的頁表,也就是每個進程都有一個虛擬地址空間。如下圖所示:
這裏寫圖片描述
在上圖中,我們發現,不同的進程中有一部分指向了相同的物理存儲器。我們知道,一般情況下,每個進程都有它自己私有的代碼,數據,堆以及棧區域,是不和其他的進程共享的。通過頁表可以映射到相應的物理存儲器。但是,有些情況下需要共享代碼和數據的。例如:每個進程都要調用相同的系統內核代碼,而每個C程序也會調用標準系統庫中的程序。此時,操作系統就會通過將不同進程中適當的虛擬頁面映射到相同的物理頁面,從而安排多個進程共享這部分代碼,而不是在每個進程中都包含。

3.虛擬存儲器作爲存儲器的保護工具

在現在的計算機系統中會提供一些手段來控制對存儲器的訪問。例如:

  1. 不允許一個用戶進程修改它的只讀區域,不允許用戶進程讀或修改任何內核中的代碼和數據結構。
  2. 不允許用戶進程讀或者寫其他進程的私有存儲器。
  3. 不允許用戶進程修改與其他進程共享的虛擬頁面。
    爲了避免以上的狀況,操作系統就會在進程的頁表中添加一些許可位。例如,添加讀/寫的許可位,當某條指令違反了這些條件時,CPU就會觸發保護故障,將其傳遞給內核中的異常處理程序。Unix shell中將這種異常報告爲:"段錯誤(segmentation fault)";
    這裏寫圖片描述

Linux虛擬存儲器

一個進程維護一個單獨的虛擬地址空間。如下圖所示:
這裏寫圖片描述
區域:一個區域就是已經存在着的虛擬存儲器的連續組塊,例如上圖中每一個框框。每個存在的虛擬頁都保存在某個區域中,不屬於某個區域的虛擬頁是不存在的,並且不能被進程引用。
內核在系統中爲每個進程維護了一個數據結構——task_struct。task_struct也叫做PCB(進程控制塊)。其中,在task_struct中有一個mm_struct,它描述了虛擬存儲器當前的狀態。它的裏面包含兩個重要的字段:pgb和mmap.而mmap又指向vm_area_struct鏈表.而每個vm_area_struct都描述了當前虛擬地址空間的一個區域.
這裏寫圖片描述
如上圖所示.

  • vm_start:指向這塊區域的起始位置.
  • vm_end:指向這塊區域的結束位置.
  • vm_port:描述這塊區域內包含所有頁面的讀寫許可權.
  • vm_flags:描述這塊區域內的頁面是否與其他進程共享,還是私有等等.
  • vm_next:指向鏈表中的下一個區域結構.

    Linux缺頁異常處理:
    假設MMU在試圖翻譯某個虛擬地址D時,觸發了一個缺頁.就會調用內核中的缺頁處理程序,其執行的步驟如下:

    1. 虛擬地址D是合法地址嗎?D存在某個區域中嗎?所以此時缺頁處理程序就會把D地址和虛擬存儲器中的每一個區域的vm_start 和vm_end進行比較,如果不存在,就會觸發一個段錯誤.這個錯誤碼爲:1.
    2. 若D合法,那麼就會試圖訪問存儲器,此時就會判斷是否合法?比如,進程是否具有讀寫這個區域的權利?如果不合法,就會返回錯誤碼爲2.
    3. 判斷上面兩個都合法,此時,內核就知道這個缺頁是因爲對合法的虛擬地址進行合法的操作造成的.此時,它就會通過合適的算法選擇一個犧牲頁面進行交換.當缺頁處理
      程序返回時,CPU重啓缺頁的指令,這條指令再次發到MMU,那麼,就不會產生缺頁中斷了.
      這裏寫圖片描述
      以上這篇博客都是從<深入理解計算機操作系統>的虛擬存儲器的章節中所學到的.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章