
在進程運行過程中,若其所要訪問的頁面不在內存而需把它們調入內存,但內存中已無空閑空間時,為了保證該進程能正常運行,
系統必須從內存中調出一頁程序或數據到磁盤的對換區中。但應將哪個頁面調出,需根據一定的算法來實現。
常見的頁面置換算法有:
1. 最佳置換算法(Optimal)
從內存中移除永遠都不再需要的頁面或者說是未來最長時間內不再被訪問的頁面,如果這樣的頁面存在,則選擇最長時間不需要訪問的頁面。采用最佳置換算法,可以保證較低的頁面更新頻率。從理論上講,由於無法預知哪一個頁面是未來最長時間內不再被訪問的,因而該算法無法實現,但是可用來衡量其他算法。
2.先進先出頁面置換算法(FIFO)
該算法總是淘汰最早進入內存的頁面,即選擇在內存中停留時間最久的頁面予以淘汰。
這個算法的實現簡單,只需要將進程已調入內存中的頁面,按照先后順序連接成一個隊列,設置一個替換指針,總是指向最老的頁面。
但是該算法與進程實際的規律並不相適應,因為在進程中,有些頁面經常被訪問,比如:含有全局變量、常用函數、例程等的頁面,FIFO不能保證這些頁面不會被淘汰。
3.最近最久未使用頁面置換算法(LRU)
在之前的FIFO算法中,依據的是各個頁面調入內存的時間,這並不能反映頁面的真實使用情況。
而LRU(Latest Recently Used)是根據頁面調入內存之后的使用情況。
由於無法預測頁面未來的情況,所以只能利用“最近的過去”來作為預測未來的方法,LRU選擇的是最近最久未使用的頁面予以淘汰。
該算法賦予每個頁面一個訪問字段,用來記錄一個頁面從上次被訪問以來所經歷的時間t,當需要淘汰一個頁面的時候,選擇現有頁面中t的值最大的頁面進行淘汰。
LRU是一種優秀的頁面置換算法,但是需要硬件的支持,為了了解一個進程在內存中各個頁面各有多少時間未被進程訪問,以及如何快速地知道哪一個頁面是最近最久未使用的頁面,需要 寄存器+棧 來支持。
(1)寄存器
為了記錄某進程在內存中各頁的使用情況,需要為每個在內存中的頁面設置一個移位寄存器,可表示為:R=R(n-1)R(n-2)...R2R1R0,當進程訪問某物理塊時,要將相應寄存器的R(n-1)位置成1。此時,定時信號將每隔一定時間(例如100ms)將寄存器右移一位。如果我們把n位寄存器的數看做是一個整數,那么具有最小數值的寄存器所對應的頁面,就是最近最久未使用的頁面。當發生缺頁時,首先將它置換出去。
(2)棧
可以利用一種特殊的棧來保存當前使用的各個頁面的頁面號,每當進程訪問某頁面的時候,便將該頁面的頁面號從棧中移除,將它壓入棧頂。因此,棧頂始終是最新被訪問頁面的編號,棧底則是最近最久未訪問頁面的頁面號,當需要置換頁面的時候,將棧底對應的頁面置換出來。
4.Clock置換算法
當采用簡單Clock算法時,只需為每頁設置一位訪問位,再將內存中的所有頁面都通過鏈接指針鏈接成一個循環隊列。
當某頁被訪問時,其訪問位被置為1。置換算法在選擇一頁淘汰時,只需檢查頁的訪問位,如果是0,就選擇將該頁換出;若為1,則重新將它置0,暫不換出,而給該頁第二次駐留內存的機會,再按照FIFO算法檢查下一個頁面。當檢查到隊列中的最后一個頁面時,若其訪問位仍為1,則再返回到隊首去檢查第一個頁面。由於該算法是循環地檢查各頁面的使用情況,故稱為Clock算法。因該算法只有一位訪問位,只能用它表示該頁是否已經使用過,而置換時是將未使用過的頁面換出去,又稱為最近未用算法NRU(Not recently used)。

