虛擬內存管理

爲什麼引入虛擬內存

傳統內存管理方式的特色

  1. 對於傳統的內存管理,做業必須一次性所有裝入內存才能夠開始運行。看成業很大時,沒法所有裝入內存,致使大的做業沒法運行,例如一個16GB的遊戲沒法在8GB的內存中直接運行。所以只有少許做業可以同時運行,系統的併發度低。
  2. 一旦做業被調入內存,就會一直常駐在內存中,可是大部分狀況下一個時間段內只要訪問做業的一部分數據進程就能正常運行,所以內存中會常駐許多暫時用不到的數據,致使內存的利用率低。

引入虛擬內存

綜合上述對於傳統內存管理的缺點,引入虛擬內存。利用局部性(包括空間局部性和時間局部性)原理,在做業裝入時,能夠將程序中很快會用到的部分裝入內存,暫時用不到的部分駐留在外存中。在程序執行過程當中,若要訪問的信息不在內存中,則利用調度將對應的信息從外存調入到內存中。若內存空間不足,則操做系統將內存中暫時用不到的信息調出到外存中。這樣在操做系統的管理下,在用戶看來內存被擴大了(例如8GB的內存能運行16GB的遊戲,實際上分配給遊戲進程的內存可能只有2GB,經過操做系統的管理讓該遊戲可以正常運行),這就是虛擬內存。算法

實際上物理內存空間的大小沒有改變,只是在邏輯空間上進行了擴充,這也是操做系統虛擬性的一個體現。併發

虛擬內存的特色

  1. 屢次性性能

    無需一次性將做業所有裝入內存,而是運行做業被分爲屢次調入內存操作系統

  2. 對換性3d

    在做業運行時無錫常駐內存,容許在做業容許過程當中,將做業調入調出內存指針

  3. 虛擬性blog

    從邏輯空間上擴充了內存的容量,使得用戶看到的內存容量遠大於實際的物理內存容量遊戲

虛擬內存的實現

虛擬內存的實現包括三種方式,分別是①請求分頁存儲管理②請求分段存儲管理③請求段頁式存儲管理,與傳統的非連續分配存儲管理(基本分頁存儲管理、基本分段存儲管理、基本段頁式存儲管理)相似,不一樣之處在於:①在程序執行過程當中,若要訪問的信息不在內存中,則有操做系統負責將所需的信息從外存調入到內存中,而後執行程序;②若內存空間不足,則操做系統會將內存中暫時用不到的信息調出到外存中。下面僅介紹請求分頁存儲管理,其餘兩種管理方式相似。進程

請求分頁存儲管理

請求分頁存儲管理的頁表以下所示:內存

頁號 內存塊號 狀態位 訪問字段 修改位 外存地址
0 null 0 0 0 X
1 b 1 10 0 Y
2 c 1 6 1 Z
  • 前兩項與基本分頁存儲管理的頁表一致,代表進程中頁號對應的內存塊號
  • 狀態位代表該頁面是否已經調入內存中
  • 訪問字段能夠記錄最近該頁被訪問了多少次,或者是上次訪問的時間,用於頁面替換算法使用
  • 修改位代表頁面在調入後是否被修改,若是沒有被修改則在被替換時能夠選擇再也不寫回外存中,而是直接被覆蓋
  • 外存地址代表進程對應的頁面在外存中的存放位置

假設如今要訪問的頁面不在內存中,即狀態位爲0,則會產生一個缺頁中斷,此時操做系統會使用中斷處理程序處理中斷,此時缺頁的進程會阻塞,放入阻塞隊伍中,等到頁面調度完成後再將其喚醒,放回到就緒隊伍中。

若是內存中有空閒塊,則會分配一個空閒塊給該進程,而後將所缺頁面從外存中調入到內存中的空閒塊中,並修改頁表;若沒有空閒塊,則利用頁面置換算法選擇一個頁面進行淘汰,並修改頁表,若被淘汰的塊沒有被修改過,則不用寫回到外存中。

例如要訪問進程的第0頁,發現第0頁沒有調入內存中,且如今有內存中的空閒塊a,則將第0頁對應的外存塊(第X塊)調入到內存塊a中,調入成功後修改的頁表以下:

頁號 內存塊號 狀態位 訪問字段 修改位 外存地址
0 a 1 0 0 X
1 b 1 10 0 Y
2 c 1 6 1 Z

地址轉換過程

在請求分頁管理中頁能夠加入快表TLB來加速查詢過程,若某個頁面被換出內存,則在快表中對應的表項也要刪除,不然可能會訪問異常。若在快表中查找到對應頁號的頁表項,則能夠直接經過頁表項中的內存塊號找到對應的物理地址。總體的地址轉換過程以下圖所示:

假設訪問快表時間爲a,訪問內存的時間爲b,訪問外存並從外存調入內存讓後更新頁表、快表的時間爲c。

  • 若在快表中找到對應表項,則訪問時間爲a(訪問快表命中)+b(訪問對應內存塊);
  • 若在快表中沒有找到而在頁表中找到對應表項,則訪問時間爲a(訪問快表未命中)+b(訪問頁表命中)+c(訪問對應內存塊) = a + 2b;
  • 若該頁面不在內存中,即訪問頁表發現控制位爲0,則訪問時間爲a(訪問快表未命中)+b(訪問頁表爲命中)+c(從外存中調入)+a(訪問快表命中)+b(訪問對應內存塊)= 2a + 2b + c

頁面置換算法

當要從外存中調入頁面時,須要使用頁面置換算法。若分配給當前程序的駐留集(也就是操做系統分配給當前程序的內存塊數,通常小於程序的總頁數)仍有空閒,則可直接使用分配的空閒塊,若沒有則要使用頁面置換算法進行頁面的置換。頁面的換入、換出須要磁盤的I/O操做,會有較大的開銷,所以一個好的頁面置換算法要追求低缺頁率。頁面置換算法包括最佳置換算法(OPT)、先進先出置換算法(FIFO)、最近最久未使用置換算法(LRU)、時鐘置換算法(CLOCK)

  1. 最佳置換算法(OPT)

每次置換最長時間內不會再被使用的頁面或之後不在使用的頁面,須要提早知道下一次要訪問的是什麼頁面,也就是頁面訪問序列,可是操做系統沒法提早預測,所以最佳置換算法是沒法實現的。最佳置換算法有最低的缺頁率,是理想化的算法。
假設頁面訪問序列爲7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1,系統爲進程分配了3個內存塊,則置換過程以下:

缺頁率爲 9/20 = 45%

  1. 先進先出置換算法(FIFO)

每次置換的頁面爲最先進入內存的頁面,能夠把調入的頁面排成一個隊伍,每次置換隊頭的頁面。假設頁面訪問序列爲3 2 1 0 3 2 4 3 2 1 0 4,系統爲進程分配3個內存塊,則置換過程以下:

缺頁率爲 9/12 = 75%

利用FIFO算法可能出現Belady異常,即爲進程分配的物理塊數增大,可是缺頁率不減反增的異常狀況,例如假設此時爲進程分配了4個內存塊,則置換過程以下:

此時缺頁率爲 10/12 = 83.3%,發生了Belady異常

  1. 最近最久未使用置換算法(LRU)

每次置換的頁面是最近最久未使用的頁面,能夠在每次頁面被使用後記錄使用時間,當須要淘汰時,淘汰時間最久的頁面。假設系統爲進程分配了4個內存塊,頁面訪問序列爲1 8 1 7 8 2 7 2 1 8 3 8 2 1 3 1 7 1 3 7,則置換過程以下:

此時缺頁率爲 6/20 = 30% ,LRU是性能最接近OPT的算法

  1. 時鐘置換算法(CLOCK)

時鐘置換算法也稱爲最近未用算法(NRU)。時鐘置換算法會爲每一個頁面設置一個訪問位,將內存中的頁面經過指針連接成一個循環隊伍。當頁面被訪問時,置該位爲1;當須要淘汰頁面時,檢測訪問位,若爲0則淘汰該頁面,若爲1則置該位爲0並沿着指針鏈順序查找下一個頁面。假設第一輪全部頁面訪問位均爲1,則一輪掃描下來後訪問位均爲0,此時通過第二輪掃描就能夠找到訪問位爲0的頁面,將其替換。每次掃描從上一次指針中止的位置開始。
假設頁面訪問序列爲 1 3 4 2 5 6 3 4 7,操做系統爲進程分配了5個內存塊,則過程以下

頁面分配策略

駐留集指請求分頁存儲管理中操做系統給進程分配的內存塊的集合,而工做集是指在某段時間內進程訪問頁面的集合,通常而言,工做集的大小不會大於工做集,不然進程運行過程當中可能頻繁地發生頁面調入調出,產生抖動/顛簸現象(頁面頻繁換入換出)。

考慮駐留集的大小,能夠分爲固定分配可變分配,即駐留集大小在程序運行期間是否能夠改變;考慮置換策略有全局置換局部置換,局部置換即發生缺頁時只能選擇本身已有的物理塊進行置換,全局置換便可以選擇操做系統保留的空閒物理塊或別的進程持有的物理塊進行置換。全局置換意味着進程的擁有的物理塊會變,所以不存在固定分配全局置換。

置換策略包括如下三種:

  1. 固定分配局部置換:操做系統爲每一個進程分配必定的物理塊,在運行期間保持不變。若進程發生缺頁,只能選擇該進程在內存中的頁面進行置換,例如上面舉的頁面置換算法都是在固定分配局部置換的前提下。這種分配策略的缺點是要實現知曉進程須要多少個物理塊才比較合適。

  2. 可變分配全局置換:剛開始時操做系統會爲進程分配必定數量的物理塊。當進程發生缺頁時,從空閒物理塊中取出一塊分配給進程,若沒有空閒物理塊,則從未鎖定的頁面中選取。只要進程發生缺頁們就會得到新的物理塊。被選擇的頁面多是任意一個進程中的頁面,所以被選擇的進程擁有的物理塊會減小,致使缺頁率上升。

  3. 可變分配局部置換:剛開始是操做系統會爲進程分配必定數量的物理塊,進程缺頁時只容許從本身在內存中的頁面進行替換。若是進程頻繁地發生缺頁,則操做系統會考慮爲該進程多分配幾個物理塊,反之則減小分配的物理塊。該策略是根據發生缺頁的頻率動態地調整進程擁有的物理塊個數

相關文章
相關標籤/搜索