操做系統核心原理-5.內存管理(中):分頁內存管理

  在上一篇介紹的幾種多道編程的內存管理模式中,以交換內存管理最爲靈活和先進。可是這種策略也存在不少重大問題,而其中最重要的兩個問題就是空間浪費和程序大小受限。那麼有什麼辦法能夠解決交換內存存在的這些問題呢?答案是分頁,它是咱們解決交換缺陷的「不二法門」。算法

1、分頁內存管理

1.1 解決問題之道

  爲了解決交換系統存在的缺陷,分頁系統橫空出世。分頁系統的核心在於:將虛擬內存空間和物理內存空間皆劃分爲大小相同的頁面,如4KB、8KB或16KB等,並以頁面做爲內存空間的最小分配單位,一個程序的一個頁面能夠存放在任意一個物理頁面裏編程

  (1)解決空間浪費碎片化問題數據結構

  因爲將虛擬內存空間和物理內存空間按照某種規定的大小進行分配,這裏咱們稱之爲頁(Page),而後按照頁進行內存分配,也就克服了外部碎片的問題。app

  (2)解決程序大小受限問題spa

  程序增加有限是由於一個程序須要所有加載到內存才能運行,所以解決的辦法就是使得一個程序無須所有加載就能夠運行。使用分頁也能夠解決這個問題,只需將當前須要的頁面放在內存裏,其餘暫時不用的頁面放在磁盤上,這樣一個程序同時佔用內存和磁盤,其增加空間就大大增長了。並且,分頁以後,若是一個程序須要更多的空間,給其分配一個新頁便可(而無需將程序倒出倒進從而提升空間增加效率)。操作系統

1.2 虛擬地址的構成與地址翻譯

  (1)虛擬地址的構成翻譯

  在分頁系統下,一個程序發出的虛擬地址由兩部分組成:頁面號和頁內偏移值,以下圖所示:設計

  例如,對於32位尋址的系統,若是頁面大小爲4KB,則頁面號佔20位,頁內偏移值佔12位。3d

  (2)地址翻譯:虛擬地址→物理地址指針

  分頁系統的核心是頁面的翻譯,即從虛擬頁面到物理頁面的映射(Mapping)。該翻譯過程以下僞代碼所示:

if(虛擬頁面非法、不在內存中或被保護)
{
    陷入到操做系統錯誤服務程序
}
else
{
    將虛擬頁面號轉換爲物理頁面號
    根據物理頁面號產生最終物理地址
}

  而這個翻譯過程由內存管理單元(MMU)完成,MMU接收CPU發出的虛擬地址,將其翻譯爲物理地址後發送給內存。內存管理單元按照該物理地址進行相應訪問後讀出或寫入相關數據,以下圖所示:

  那麼,這個翻譯是怎麼實現的呢?答案是查頁表,對於每一個程序,內存管理單元MMU都爲其保存一個頁表,該頁表中存放的是虛擬頁面到物理頁面的映射。每當爲一個虛擬頁面尋找到一個物理頁面以後,就在頁表裏增長一條記錄來保留該映射關係。固然,隨着虛擬頁面進出物理內存,頁表的內容也會不斷更新變化。

1.3 頁表

  頁表的根本功能是提供從虛擬頁面到物理頁面的映射。所以,頁表的記錄條數與虛擬頁面數相同。此外,內存管理單元依賴於頁表來進行一切與頁面有關的管理活動,這些活動包括判斷某一頁面號是否在內存裏,頁面是否受到保護,頁面是否非法空間等等。

  頁表的一個記錄所包括的內容以下圖所示:

  因爲頁表的特殊地位,決定了它是由硬件直接提供支持,即頁表是一個硬件數據結構。

1.4 分頁系統的優缺點

  優勢:

  (1)分頁系統不會產生外部碎片,一個進程佔用的內存空間能夠不是連續的,而且一個進程的虛擬頁面在不須要的時候能夠放在磁盤中。

  (2)分頁系統能夠共享小的地址,即頁面共享。只須要在對應給定頁面的頁表項裏作一個相關的記錄便可。

  缺點:頁表很大,佔用了大量的內存空間。

1.5 缺頁中斷處理

  在分頁系統中,一個虛擬頁面既有可能在物理內存,也有可能保存在磁盤上。若是CPU發出的虛擬地址對應的頁面不在物理內存,就將產生一個缺頁中斷,而缺頁中斷服務程序負責將須要的虛擬頁面找到並加載到內存。缺頁中斷的處理步驟以下,省略了中間不少的步驟,只保留最核心的幾個步驟:

2、頁面置換算法

  若是發生了缺頁中斷,就須要從磁盤上將須要的頁面調入內存。若是內存沒有多餘的空間,就須要在現有的頁面中選擇一個頁面進行替換。使用不一樣的頁面置換算法,頁面更換的順序也會各不相同。若是挑選的頁面是以後很快又要被訪問的頁面,那麼系統將很開再次產生缺頁中斷,由於磁盤訪問速度遠遠內存訪問速度,缺頁中斷的代價是很是大的。所以,挑選哪一個頁面進行置換不是隨隨便便的事情,而是有要求的。

2.1 頁面置換的目標

  頁面置換時挑選頁面的目標主要在於下降隨後發生缺頁中斷的次數或機率

  所以,挑選的頁面應當是隨後至關長時間內不會被訪問的頁面,最好是不再會被訪問的頁面。BTW,若是可能,最好選擇一個沒有修改過的頁面,這樣替換時就無須將被替換頁面的內容寫回磁盤,從而進一步加快缺頁中斷的響應速度。

  因此,爲了達到這個目的,先驅們設計出了各類各樣的頁面置換算法,下面就來看看這些算法。

2.2 隨機更換算法

  在須要替換頁面的時候,產生一個隨機頁面號,從而替換與該頁面號對應的物理頁面。遺憾的是,隨機選出的被替換的頁面不太多是隨後至關長時間內不會被訪問的頁面。也就是說,這種算法難以保證最小化隨後的缺頁中斷次數。事實上,這種算法的效果至關差。

2.3 先進先出算法

  顧名思義,先進先出(FIFO,First In First Out)算法的核心是更換最先進入內存的頁面,其實現機制是使用鏈表將全部在內存中的頁面按照進入時間的遲早連接起來,而後每次置換鏈表頭上的頁面就好了,而新加進來的頁面則掛在鏈表的末端,以下圖所示:

  FIFO的優勢是簡單且容易實現,缺點是若是最早加載進來的頁面是常常被訪問的頁面,那麼就可能形成被訪問的頁面替換到磁盤上,致使很快就須要再次發生缺頁中斷,從而下降效率。

2.4 第二次機會算法

  因爲FIFO只考慮進入內存的時間,不關心一個頁面被訪問的頻率,從而有可能形成替換掉一個被常常訪問的頁面而形成效率低下。那麼,能夠對FIFO進行改進:在使用FIFO更換一個頁面時,須要看一下該頁面是否在最近被訪問過,若是沒有被訪問過,則替換該頁面。反之,若是最近被訪問過(經過檢查其訪問位的取值),則不替換該頁面,而是將該頁面掛到鏈表末端,並將該頁面進入內存的時間設置爲當前時間,並將其訪問位清零。這樣,對於最近被訪問過的頁面來講,至關於給了它第二次機會。

  例如,當A頁面最近被訪問過,即其訪問位R的值爲1,則使用第二次機會算法以後,鏈表的格局以下圖所示:

  第二次機會算法簡單、公平且容易實現。可是,每次給予一個頁面第二次機會時,將其移動到鏈表末端須要耗費時間。此外,頁面的訪問位只在頁面替換進行掃描時纔可能清零,因此其時間局域性體現得很差,訪問位爲1的頁面多是好久之前訪問的,時間上的分辨粒度太粗,從而影響頁面替換的效果。

2.5 時鐘算法

  爲了改善第二次機會算法的缺點,先驅們提出了時鐘算法。時鐘算法的核心思想是:將頁面排成一個時鐘的形狀,該時鐘有一個針臂,每次須要更換頁面時,咱們從針臂所指的頁面開始檢查。若是當前頁面的訪問位爲0,即從上次檢查到此次,該頁面沒有被訪問過,將該頁面替換。反之,就將其訪問位清零,並順時針移動指針到下一個頁面。重複這些步驟,直到找到一個訪問位爲0的頁面。

  例以下圖所示的一個時鐘,指針指向的頁面是F,所以第一個被考慮替換的頁面是F。若是頁面F的訪問位爲0,F將被替換。若是F的訪問位爲1,則F的訪問位清零,指針移動到頁面G。

  從表面上看,它和第二次機會算法相似,都是訪問位爲0就更換,反之則再給一次機會。可是,它和第二次機會算法仍是有幾點不一樣:

  (1)他們的數據結構不同,第二次機會使用的是鏈表,時鐘算法使用的是索引(整數指針)。這樣,其使用的內存空間不同。

  (2)第二次機會須要使用額外的內存,而時鐘算法能夠直接使用頁表。使用頁表的好處是無需額外的空間,更大的好處是頁面的訪問位會按期自動清零,這樣將使得時鐘算法的時間分辨粒度較第二次機會算法高,從而取得更好的頁面替換效果。

  時鐘算法的精髓是第二次機會,其缺點也就和第二次機會算法同樣:過於公平,沒有考慮到不一樣頁面調用頻率的不一樣,有可能換出不該該或不能換出的頁面,還可能形成無限循環。

PS:至此,隨機、FIFO、第二次機會與時鐘算法的介紹就到此結束,這四種算法都是屬於「公平算法」,即全部的頁面都或多或少地給予公平待遇,沒有頁面得到特殊待遇。可是這種公平實現方式,會使效率受到必定影響,這時由於個體對於整個系統的貢獻沒有被區別對待,形成貢獻大的和貢獻小的待遇同樣,天然會影響整個系統的效率。

2.6 最優更換算法

  咱們知道,最理想的頁面替換算法是選擇一個不再會被訪問的頁面進行替換。若是不存在這樣的頁面,那至少選擇一個在隨後最長時間內不會被訪問的頁面進行替換。這樣,咱們就能夠保證在隨後發生缺頁中斷的次數最小或機率最低,這種算法就是最有替換算法。

  可是,咱們無法知道一個頁面隨後多長時間不會被訪問,所以最優更換算法在實際中無法實現,那麼爲何要介紹最有更換算法呢?這是爲了定義一個標杆,以此來評判其餘算法的優劣。

2.7 NRU(最近未被使用)算法

  顧名思義,NRU就是選擇一個在最近一段時間內沒有被訪問過的頁面進行替換,這是基於程序訪問的時空局域性。由於根據時空局域性原理,一個最近沒有被訪問的頁面,在隨後的時間裏也不太可能被訪問,而NRU的實現方式就是利用頁面的訪問和修改位。

  每一個頁面都有一個訪問位和一個修改位,凡是對頁面進行讀寫操做時,訪問位被設置爲1。當進程對頁面進行讀寫操做時,修改位設置爲1。根據這兩個位的狀態來對頁面進行分類的話,能夠分紅如下四種頁面類型:一、二、三、4。

  有了這個分類,NRU算法就按照這四類頁面的順序依次尋找能夠替換的頁面。若是全部頁面皆被訪問和修改過,那也只能從中替換掉一個頁面,所以NRU算法老是會終結的。

  固然,這種分類比較籠統,在同一類頁面裏,咱們沒有辦法分辨出哪一類被訪問的時間更近一些。即在某些狀況下,咱們替換的可能並非最近沒有被使用的頁面。

2.8 LRU(最近最少使用)算法

  與NRU算法相比,LRU算法不只考慮最近是否用過,還要考慮最近使用的頻率。這裏是基於過去的數據預測將來:若是一個頁面被訪問的頻率低,那麼之後極可能也用不到。

  LRU算法的實現必須以某種方式記錄每一個頁面被訪問的次數,這是個至關大的工做量。最簡單的方式就是在頁表的記錄項裏增長一個計數域,一個頁面被訪問一次,這個計數器的值就增長1。因而,當須要更換頁面時,只須要找到計數域值最小的頁面替換便可,該頁面便是最近最少使用的頁面。另外一種簡單實現方式就是用一個鏈表將全部頁面連接起來,最近被使用的頁面在鏈表頭,最近未被使用的放在鏈表尾。在每次頁面訪問時對這個鏈表進行更新,使其保持最近被使用的頁面在鏈表頭。

  LRU算法雖然很好,可是實現成本高(須要分辨出不一樣頁面中哪一個頁面時最近最少使用的),而且時間代價大(每次頁面訪問發生時都須要更新記錄)。所以,通常的商業操做系統都沒有采納LRU頁面更新算法。

2.9 工做集算法

  因爲不可能精確地肯定那個頁面是最近最少使用的,那就乾脆不花費這個力氣,只維持少許的信息使得咱們選出的替換頁面不太多是立刻又會使用的頁面便可。這種少許的信息就是工做集信息

  工做集概念來源於程序訪問的時空侷限性,即在一段時間內,程序訪問的頁面將侷限在一組頁面集合上。例如,最近k次訪問均發生在某m個頁面上,那麼m就是參數爲k時的工做集。咱們用w(k,t)來表示在時間t時k次訪問所涉及的頁面數量。

  顯然,隨着k的增加,w(k,t)的值也隨之增加;可是當k增加到某個數值以後,w(k,t)的值將增加極其緩慢甚至接近停滯,並維持一段時間的穩定,以下圖所示:

  由上圖能夠看出,若是一個程序在內存裏面的頁面數與其工做集大小相等或者超過工做集,則該程序可在一段時間內不會發生缺頁中斷。若是其在內存的頁面數小於工做集,則發生缺頁中斷的頻率將增長,甚至發生內存抖動。

  所以,工做計算法的目標就是維持當前的工做集的頁面在物理內存裏面。每次頁面更換時,尋找一個不屬於當前工做集的頁面替換便可。這樣,咱們再尋找頁面時只須要將頁面分離爲兩大類便可:當前工做集內頁面和當前工做集外頁面。如此,只要找到一個飛當前工做集的頁面,將其替換便可。

  工做集算法的優勢:實現簡單,只須要在頁表的每一個記錄增長一個虛擬時間域便可。並且,這個時間域不是每次發生訪問時都須要更新,而是在須要更換頁面時,頁面更換算法對其進行修改,所以時間成本也不大。

  工做集算法的缺點:每次掃描頁面進行替換時,有可能須要掃描整個頁表。然而,並非全部頁面都內存裏,所以掃描過程當中的一大部分時間將是無用功。另外,因爲其數據結構是線性的,會形成每次都按一樣的順序進行掃描,顯得不太公平。

2.10 工做集時鐘算法

  鑑於工做集算法的缺點,先驅們將工做集算法與時鐘算法結合起來,設計出了工做集時鐘算法,即使用工做集算法的原理,可是將頁面的掃描順序按照時鐘的形式組織起來。這樣每次須要替換頁面時,從指針指向的頁面開始掃描,從而達到更加公平的狀態。並且,按時鐘組織的頁面只是在內存裏面的頁面,在內存外的頁面不放在時鐘圈裏,從而提升實現效率

  鑑於其時間與空間上的優點,工做集時鐘算法被大多商業操做系統所採納

參考資料

鄒恆明,《操做系統之哲學原理》,機械工業出版社

 

相關文章
相關標籤/搜索