1. 程式人生 > >作業系統的記憶體分頁管理、虛擬記憶體介紹

作業系統的記憶體分頁管理、虛擬記憶體介紹

今天這篇關於作業系統的方面的技術文章,我們繼續為各位朋友們講解關於作業系統的記憶體方面的內容。今天 我們主要為各位朋友們講解記憶體分頁管理、虛擬記憶體介紹。傳統儲存管理方式的特徵
上一節所討論的各種記憶體管理策略都是為了同時將多個程序儲存在記憶體中以便允許多道程式設計。它們都具有以下兩個共同的特徵: 
1) 一次性
作業必須一次性全部裝入記憶體後,方能開始執行。這會導致兩種情況發生: • 當作業很大,不能全部被裝入記憶體時,將使該作業無法執行;
• 當大量作業要求執行時,由於記憶體不足以容納所有作業,只能使少數作業先執行,導致多道程式度的下降。

2) 駐留性
作業被裝入記憶體後,就一直駐留在記憶體中,其任何部分都不會被換出,直至作業執行結束。執行中的程序,會因等待I/O而被阻塞,可能處於長期等待狀態。


由以上分析可知,許多在程式執行中不用或暫時不用的程式(資料)佔據了大量的記憶體空間,而一些需要執行的作業又無法裝入執行,顯然浪費了寶貴的記憶體資源。 
區域性性原理
要真正理解虛擬記憶體技術的思想,首先必須瞭解計算機中著名的區域性性原理。著名的 Bill Joy (SUN公司CEO)說過:”在研究所的時候,我經常開玩笑地說快取記憶體是電腦科學中唯一重要的思想。事實上,髙速快取技術確實極大地影響了計算機系統的設計。“快表、 頁快取記憶體以及虛擬記憶體技術從廣義上講,都是屬於快取記憶體技術。這個技術所依賴的原理就是區域性性原理。區域性性原理既適用於程式結構,也適用於資料結構(更遠地講,Dijkstra 著名的關於“goto語句有害”的論文也是出於對程式區域性性原理的深刻認識和理解)。


區域性性原理表現在以下兩個方面: • 時間區域性性:如果程式中的某條指令一旦執行,不久以後該指令可能再次執行;如果某資料被訪問過,不久以後該資料可能再次被訪問。產生時間區域性性的典型原因,是由於在程式中存在著大量的迴圈操作。
• 空間區域性性:一旦程式訪問了某個儲存單元,在不久之後,其附近的儲存單元也將被訪問,即程式在一段時間內所訪問的地址,可能集中在一定的範圍之內,這是因為指令通常是順序存放、順序執行的,資料也一般是以向量、陣列、表等形式簇聚儲存的。

時間區域性性是通過將近來使用的指令和資料儲存到快取記憶體儲存器中,並使用快取記憶體的層次結構實現。空間區域性性通常是使用較大的快取記憶體,並將預取機制整合到快取記憶體控制邏輯中實現。虛擬記憶體技術實際上就是建立了 “記憶體一外存”的兩級儲存器的結構,利用區域性性原理實現髙速快取。 

虛擬儲存器的定義和特徵
基於區域性性原理,在程式裝入時,可以將程式的一部分裝入記憶體,而將其餘部分留在外存,就可以啟動程式執行。在程式執行過程中,當所訪問的資訊不在記憶體時,由作業系統將所需要的部分調入記憶體,然後繼續執行程式。另一方面,作業系統將記憶體中暫時不使用的內容換出到外存上,從而騰出空間存放將要調入記憶體的資訊。這樣,系統好像為使用者提供了一個比實際記憶體大得多的儲存器,稱為虛擬儲存器。

之所以將其稱為虛擬儲存器,是因為這種儲存器實際上並不存在,只是由於系統提供了部分裝入、請求調入和置換功能後(對使用者完全透明),給使用者的感覺是好像存在一個比實際實體記憶體大得多的儲存器。虛擬儲存器的大小由計算機的地址結構決定,並非是記憶體和外存的簡單相加。虛擬儲存器有以下三個主要特徵: • 多次性,是指無需在作業執行時一次性地全部裝入記憶體,而是允許被分成多次調入記憶體執行。
• 對換性,是指無需在作業執行時一直常駐記憶體,而是允許在作業的執行過程中,進行換進和換出。
• 虛擬性,是指從邏輯上擴充記憶體的容量,使使用者所看到的記憶體容量,遠大於實際的記憶體容量。

虛擬記憶體技術的實現
虛擬記憶體中,允許將一個作業分多次調入記憶體。釆用連續分配方式時,會使相當一部分記憶體空間都處於暫時或“永久”的空閒狀態,造成記憶體資源的嚴重浪費,而且也無法從邏輯上擴大記憶體容量。因此,虛擬記憶體的實需要建立在離散分配的記憶體管理方式的基礎上。虛擬記憶體的實現有以下三種方式: • 請求分頁儲存管理。
• 請求分段儲存管理。
• 請求段頁式儲存管理。

不管哪種方式,都需要有一定的硬體支援。一般需要的支援有以下幾個方面: • 一定容量的記憶體和外存。
• 頁表機制(或段表機制),作為主要的資料結構。
• 中斷機構,當用戶程式要訪問的部分尚未調入記憶體,則產生中斷。
• 地址變換機構,邏輯地址到實體地址的變換。

請求分頁系統建立在基本分頁系統基礎之上,為了支援虛擬儲存器功能而增加了請求調頁功能和頁面置換功能。請求分頁是目前最常用的一種實現虛擬儲存器的方法。

在請求分頁系統中,只要求將當前需要的一部分頁面裝入記憶體,便可以啟動作業執行。在作業執行過程中,當所要訪問的頁面不在記憶體時,再通過調頁功能將其調入,同時還可以通過置換功能將暫時不用的頁面換出到外存上,以便騰出記憶體空間。

為了實現請求分頁,系統必須提供一定的硬體支援。除了需要一定容量的記憶體及外存的計算機系統,還需要有頁表機制、缺頁中斷機構和地址變換機構。 
頁表機制
請求分頁系統的頁表機制不同於基本分頁系統,請求分頁系統在一個作業執行之前不要求全部一次性調入記憶體,因此在作業的執行過程中,必然會出現要訪問的頁面不在記憶體的情況,如何發現和處理這種情況是請求分頁系統必須解決的兩個基本問題。為此,在請求頁表項中增加了四個欄位,如圖3-24所示。

圖3-24 請求分頁系統中的頁表項

增加的四個欄位說明如下: • 狀態位P:用於指示該頁是否已調入記憶體,供程式訪問時參考。
• 訪問欄位A:用於記錄本頁在一段時間內被訪問的次數,或記錄本頁最近己有多長時間未被訪問,供置換演算法換出頁面時參考。
• 修改位M:標識該頁在調入記憶體後是否被修改過。
• 外存地址:用於指出該頁在外存上的地址,通常是物理塊號,供調入該頁時參考。

缺頁中斷機構
在請求分頁系統中,每當所要訪問的頁面不在記憶體時,便產生一個缺頁中斷,請求作業系統將所缺的頁調入記憶體。此時應將缺頁的程序阻塞(調頁完成喚醒),如果記憶體中有空閒塊,則分配一個塊,將要調入的頁裝入該塊,並修改頁表中相應頁表項,若此時記憶體中沒有空閒塊,則要淘汰某頁(若被淘汰頁在記憶體期間被修改過,則要將其寫回外存)。

缺頁中斷作為中斷同樣要經歷,諸如保護CPU環境、分析中斷原因、轉入缺頁中斷處理程式、恢復CPU環境等幾個步驟。但與一般的中斷相比,它有以下兩個明顯的區別: • 在指令執行期間產生和處理中斷訊號,而非一條指令執行完後,屬於內部中斷。
• 一條指令在執行期間,可能產生多次缺頁中斷。

地址變換機構
請求分頁系統中的地址變換機構,是在分頁系統地址變換機構的基礎上,為實現虛擬記憶體,又增加了某些功能而形成的。

圖3-25請求分頁中的地址變換過程

如圖3-25所示,在進行地址變換時,先檢索快表: • 若找到要訪問的頁,便修改頁表項中的訪問位(寫指令則還須重置修改位),然後利用頁表項中給出的物理塊號和頁內地址形成實體地址。
• 若未找到該頁的頁表項,應到記憶體中去查詢頁表,再對比頁表項中的狀態位P,看該頁是否已調入記憶體,未調入則產生缺頁中斷,請求從外存把該頁調入記憶體。


程序執行時,若其訪問的頁面不在記憶體而需將其調入,但記憶體已無空閒空間時,就需要從記憶體中調出一頁程式或資料,送入磁碟的對換區。

選擇調出頁面的演算法就稱為頁面置換演算法。好的頁面置換演算法應有較低的頁面更換頻率,也就是說,應將以後不會再訪問或者以後較長時間內不會再訪問的頁面先調出。

常見的置換演算法有以下四種。 
1. 最佳置換演算法(OPT)
最佳(Optimal, OPT)置換演算法所選擇的被淘汰頁面將是以後永不使用的,或者是在最長時間內不再被訪問的頁面,這樣可以保證獲得最低的缺頁率。但由於人們目前無法預知程序在記憶體下的若千頁面中哪個是未來最長時間內不再被訪問的,因而該演算法無法實現。

最佳置換演算法可以用來評價其他演算法。假定系統為某程序分配了三個物理塊,並考慮有以下頁面號引用串:
7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1

程序執行時,先將7, 0, 1三個頁面依次裝入記憶體。程序要訪問頁面2時,產生缺頁中斷,根據最佳置換演算法,選擇第18次訪問才需調入的頁面7予以淘汰。然後,訪問頁面0時,因為已在記憶體中所以不必產生缺頁中斷。訪問頁面3時又會根據最佳置換演算法將頁面1淘汰……依此類推,如圖3-26所示。從圖中可以看出釆用最佳置換演算法時的情況。

可以看到,發生缺頁中斷的次數為9,頁面置換的次數為6。

2. 先進先出(FIFO)頁面置換演算法
優先淘汰最早進入記憶體的頁面,亦即在記憶體中駐留時間最久的頁面。該演算法實現簡單,只需把調入記憶體的頁面根據先後次序連結成佇列,設定一個指標總指向最早的頁面。但該演算法與程序實際執行時的規律不適應,因為在程序中,有的頁面經常被訪問。

這裡仍用上面的例項,釆用FIFO演算法進行頁面置換。程序訪問頁面2時,把最早進入記憶體的頁面7換出。然後訪問頁面3時,再把2, 0, 1中最先進入記憶體的頁換出。由圖 3-27可以看出,利用FIFO演算法時進行了 12次頁面置換,比最佳置換演算法正好多一倍。

FIFO演算法還會產生當所分配的物理塊數增大而頁故障數不減反增的異常現象,這是由 Belady於1969年發現,故稱為Belady異常,如圖3-28所示。只有FIFO演算法可能出現Belady 異常,而LRU和OPT演算法永遠不會出現Belady異常。

3. 最近最久未使用(LRU)置換演算法
選擇最近最長時間未訪問過的頁面予以淘汰,它認為過去一段時間內未訪問過的頁面,在最近的將來可能也不會被訪問。該演算法為每個頁面設定一個訪問欄位,來記錄頁面自上次被訪問以來所經歷的時間,淘汰頁面時選擇現有頁面中值最大的予以淘汰。

再對上面的例項釆用LRU演算法進行頁面置換,如圖3-29所示。程序第一次對頁面2訪問時,將最近最久未被訪問的頁面7置換出去。然後訪問頁面3時,將最近最久未使用的頁面1換出。

在圖3-29中,前5次置換的情況與最佳置換演算法相同,但兩種演算法並無必然聯絡。實際上,LRU演算法根據各頁以前的情況,是“向前看”的,而最佳置換演算法則根據各頁以後的使用情況,是“向後看”的。

LRU效能較好,但需要暫存器和棧的硬體支援。LRU是堆疊類的演算法。理論上可以證明,堆疊類演算法不可能出現Belady異常。FIFO演算法基於佇列實現,不是堆疊類演算法。 
4. 時鐘(CLOCK)置換演算法
LRU演算法的效能接近於OPT,但是實現起來比較困難,且開銷大;FIFO演算法實現簡單,但效能差。所以作業系統的設計者嘗試了很多演算法,試圖用比較小的開銷接近LRU的效能,這類演算法都是CLOCK演算法的變體。

簡單的CLOCK演算法是給每一幀關聯一個附加位,稱為使用位。當某一頁首次裝入主存時,該幀的使用位設定為1;當該頁隨後再被訪問到時,它的使用位也被置為1。對於頁替換演算法,用於替換的候選幀集合看做一個迴圈緩衝區,並且有一個指標與之相關聯。當某一頁被替換時,該指標被設定成指向緩衝區中的下一幀。當需要替換一頁時,作業系統掃描緩衝區,以查詢使用位被置為0的一幀。每當遇到一個使用位為1的幀時,作業系統就將該位重新置為0;如果在這個過程開始時,緩衝區中所有幀的使用位均為0,則選擇遇到的第一個幀替換;如果所有幀的使用位均為1,則指標在緩衝區中完整地迴圈一週,把所有使用位都置為0,並且停留在最初的位置上,替換該幀中的頁。由於該演算法迴圈地檢查各頁面的情況,故稱為CLOCK演算法,又稱為最近未用(Not Recently Used, NRU)演算法。

CLOCK演算法的效能比較接近LRU,而通過增加使用的位數目,可以使得CLOCK演算法更加高效。在使用位的基礎上再增加一個修改位,則得到改進型的CLOCK置換演算法。這樣,每一幀都處於以下四種情況之一: 1. 最近未被訪問,也未被修改(u=0, m=0)。
2. 最近被訪問,但未被修改(u=1, m=0)。
3. 最近未被訪問,但被修改(u=0, m=1)。
4. 最近被訪問,被修改(u=1, m=1)。

演算法執行如下操作步驟: 1. 從指標的當前位置開始,掃描幀緩衝區。在這次掃描過程中,對使用位不做任何修改。選擇遇到的第一個幀(u=0, m=0)用於替換。
2. 如果第1)步失敗,則重新掃描,查詢(u=0, m=1)的幀。選擇遇到的第一個這樣的幀用於替換。在這個掃描過程中,對每個跳過的幀,把它的使用位設定成0。
3. 如果第2)步失敗,指標將回到它的最初位置,並且集合中所有幀的使用位均為0。重複第1步,並且如果有必要,重複第2步。這樣將可以找到供替換的幀。

改進型的CLOCK演算法優於簡單CLOCK演算法之處在於替換時首選沒有變化的頁。由於修改過的頁在被替換之前必須寫回,因而這樣做會節省時間。

好了,關於計算機的作業系統中的記憶體的管理方面的內容,我們暫時就介紹到這裡吧