操作系統——內存管理學習筆記


操作系統——內存管理

Basic memory management

Base and Limit register

在這里插入圖片描述

將上圖這塊稱為MMU

Swapping

在這里插入圖片描述

操作系統中的內存是動態分配的,如圖所示:

  1. A進程啟動,占用一部分內存
  2. B進程啟動,占用一部分內存
  3. C進程啟動,占用一部分內存
  4. A進程結束,又會將之前A占用的內存釋放
  5. 隨后又啟動D進程,占用掉一部分內存
  6. B進程結束,釋放掉B占用的內存
  7. 再啟動A,這時又會划分給A一部分內存

這些動態的對內存的規划,就要用到swap交換內存,所以一般在linux系統中對交換分區的分區大小是和內存大小一致,或者內存的兩倍,就是為了保證交換分區足夠大,且高效。

在這里插入圖片描述

如b圖,在程序A中,代碼段存在A-Program中,是相對固定的大小。數據段A-Data挨着代碼段,當new數據的時候數據段就會增長。在這個進程的地址空間的高端地址會放一個A-Stack,當每次調用一個函數,就會壓入A-Stack中(壓入棧的叫棧幀),當從函數退出的時候就會彈棧。當數據段和棧碰在一起的時候就溢出了。

Virtual memory

Memory Management with Bit Maps

在這里插入圖片描述

Memory Management with Linked Lists

在這里插入圖片描述

  1. 用Bit Map管理內存

    ​ 如圖(b),A、B、C、D、E表示進程,陰影表示未被分配的內存區域。將內存划分為一個一個的小塊,如A進程占用了5個小塊。在操作系統的內存中維護一張表map,表中每一個bit對應內存中的一個小塊。入A進程與表的第一行的對應,如果該小塊內存被占用就用1來表示,如果未被占用就用0來表示。這樣維護一張Bit Map就可以管理內存。

  2. 拉一張鏈表來管理內存

    ​ 如圖(c),鏈表中一個結點有四個數據:第一個為P/H,如果是P則表示是進程在使用這塊內存(Process),如果是H,則表示這塊內存未被分配(Hole)。第二個為起始位置,表示這個結點所表示的這塊內存的起始位置。第三個表示長度,表示這個結點所表示的內存所占用的長度。第四個指示下一個結點。

    ​ 當進程所使用的內存被收回后,應該維護這個鏈表使得保持一致,不可能出現兩個Hole連在一起,當一個進程被釋放內存后,如果左右有Hole,應該將其合在一起,改變起始位置和長度。

Virtual Memory Paging

​ 當運行一個占用內存很大的進程時,由於物理內存不夠用就需要用到虛擬內存。把physical內存分成塊,一會兒讓這個進程的這部分用,一會兒讓另外一部分用。這樣就會產生一個類似於swap的從內存和硬盤里的轉化的過程。

在這里插入圖片描述

​ 這里的MMU(Memory management unit)是將虛擬地址轉化為實際的物理地址,轉化的過程比最開始的那個復雜。首先得知道你要訪問的內存在不在物理內存里面,如果不在physical memory里面,就把你要訪問的地址在內存中找個地方加載進來,然后才再去訪問它。把不存在的地址加載進內存這件事需要硬件來做,也需要操作系統(操作系統的一個功能——請求分頁,用來支持虛擬內存的一個功能)來做。

​ 要知道這個進程里的哪些頁在內存里面,哪些不在,如果在,在內存的什么地方,就需要用到虛擬內存里面用到的一個技術——分頁(Paging)。MMU會和分頁結合起來完成這個虛擬內存。

分頁,就是把內存分成固定大小的頁幀,把進程里面訪問的空間也分成一個一個的頁,每個頁對應一個頁幀,每一個頁幀在物理內存可以是不連續的,但是有一個辦法可以知道頁到頁幀之間的轉換,這個機制就叫頁表(頁表存放在操作系統里面)。每個進程都有一個PCB,PCB里有一個數據結構就指向這個進程的頁表,每個進程要運行都要一個頁表,每個進程的頁表都是不一樣的。

在這里插入圖片描述

Address Translation Architecture

​ logical address也就是虛擬地址,是一個二進制數,低位d表示偏移量直接拿過去,拿到高位(就是p,頁幀的編號),在page table中把p作為下表找到對應的f,和剛剛的d拼到一塊就是物理地址。

​ 這張page table是操作系統在加載這個進程的時候建起來的,把這個進程需要用到的頁都加載進這個表。

在這里插入圖片描述

​ 缺頁中斷:page table里的f並不是都建好,它是建了一部分,所以有可能會出現:用邏輯地址p查表發現f沒有,也就是說要訪問的物理頁不在內存里面,這個時候就會產生缺頁中斷。就會跑到操作系統里,操作系統就會找到一塊內存,然后把要訪問的頁從磁盤里面放到內存里面,然后把這個地址填上,重新執行這條指令。

下圖是一個MMU,下面是邏輯地址,上面的是物理地址。實際的page table並不是和圖中一樣只有兩部分,Present/absent表示這一項所對應的物理地址在或者不在,1表示在,0表示不在,不在就會產生缺頁中斷。

Internal operation of MMU with 16 4KB pages

實際圖中偏移量的比特決定了頁面的大小,比如下圖的偏移量是12個bits,所以頁面大小為4Kb(12個bit,就是2^12 = 1024*4,1 kb = 1024 bit,所以就是4kb了),如果是13個bits,那就就要double一下,即8Kb。

在這里插入圖片描述

​ 由於頁表也在內存中,所以這種方式需要訪問兩次內存:第一次查表找到實際的物理地址,第二次訪問真正的內存。所以在時間上會稍慢一些。

​ 上面的方案是查的時候先有一個頁幀的編號,再有一個偏移量,但這時候進程的頁表會很大,很多時候頁表中很多項都沒有加載到內存里面,那些項在操作系統內存中占着,但是沒有數據,沒有對應關系,占的空間會很大。所以將頁表分為二級頁表

在這里插入圖片描述

​ 二級頁表的PT1是頁目錄(Top-level page table)的下標,用它可以找到頁表的位置,再用PT2在找到的頁表中找到頁幀,再結合偏移量offset找到physical memory。

​ PT1對應的頁表在內存中的位置可以是空的,所以Second-level page table里的某些表可以不放在內存里面,也就是用Top-level page table里的一項代替Second-level page table里的一張表,減少了內存的大小。當然還可以分成三項、四項......但是這樣的話所訪問內存的次數就會增加,所以是用時間換取空間。

Typical page table entry

下圖是一個典型的頁表項,表示一個頁表項可以存什么信息。

在這里插入圖片描述

  1. Present/absent:占一個bit位,如果是0表示這一頁在內存中不存在,如果是1表示在內存中存在
  2. Page frame number:如果Present/absent為1,則表示這一頁的頁幀,如果為0,則表示這一也在swap分區(硬盤中)中的位置。
  3. Protection:保護位,保存一些保護信息,表明這個頁的權限信息,比如:只讀的、讀寫的......
  4. Modified:如果物理頁幀做過修改,就將這個位置位。
  5. Referenced:每次對這個頁面訪問的時候,就會置這個位,用來表示這個頁面有沒有被訪問過
  6. Caching disabled:是否允許cache這個頁

TLBs——Translation Lookaside Buffers

在這里插入圖片描述

​ 為了提高效率,在MMU的這一套硬件系統里加了一個cache(TLB),在一個進程中第一次通過邏輯頁查找,查到頁幀(Page frame)、Protection、Modified,然后將其存到這個TLB中,等下次訪問這個邏輯頁的時候就不用去查表,直接在TLB中就可以返回頁幀,以達到加速查找。TLB中還有一項Valid,如果為0則表明這一項是無效的,是1才是有效的。

​ 可以看出這一張TLB中所有的Virtual page是針對一個進程的,所以當出現進程切換,這整個TLB的內容全就無效了,因為不同進程的對應關系也不同。所以進程切換的開銷很大。進程也因為這個TLB所以越跑越快,因為整個表建立好后就快速了。

Inverted Page Tables

在這里插入圖片描述

​ 原來的是根據邏輯頁去查找實際的物理頁,最左邊的圖,表中有2^52個頁,根據邏輯地址去找,找到某一項。這樣的話,這樣的頁表是針對每個進程都有這樣一個頁表,這樣一個頁表中可能大部分的項都是空的。

​ 反向頁表,假如只要256MB的物理地址,就有2^16個4KB大小的page frames(頁幀),那么就看這么多物理的頁幀到底是哪個虛擬的頁或者哪個進程在用的,把Virtual page做一個hash得到一個hash值,hash的范圍就這個物理的頁幀的范圍里面,得到hash值后就能找到一個列表,這個列表里面就對應了一個Virtual page和physical page 的對應關系。如果hash出來這個值找到了一個鏈表(至於為什么是鏈表,是為了解決hash沖突),那就找到了這個物理頁和邏輯頁的對應關系,如果沒找到就說明這個邏輯頁不存在。

Page replacement algorithms

Optimal Page Replacement Algorithm

​ 最優的頁面替換算法就是能看到未來,被替換的頁面是內存中未來被使用最少的頁面,但這種算法雖然是最優的,卻是不可實現的,因為未來是無法預知的。這個算法可以用來評估其他的算法。

Not Recently Used Page Replacement Algorithm

  • Each page has Reference bit,Modified bit
    • bits are set when page is referenced, modified。當這個頁面被訪問的時候就將referenced位置1,當這個頁面被修改的時候就將Modified置1。
    • 這兩個位也可能被清。比如后台運行的page Demain的程序,周期掃描這個頁表,當發現某些被modified,就嘗試把這些頁回寫到磁盤里,然后將Modified清0。
    • 有時候也會定期的把reference清0,配合頁面替換算法,清的時間是知道的,當下次查這個reference的時候發現又被置1,說明至少在清的時間到再次查的時間里被訪問過。
  • Page are classified(分類)
    1. not referenced,not modified
    2. not referenced,modified(這里做一個解釋:有可能被訪問且修改后,referenced被清0了,但modifies沒有被清,也就是沒寫到磁盤里去)
    3. referenced,not modified
    4. referenced,modified
  • NRU removes page at random
    • from lowest numbered non empty class
    • 就是按上面分的類,從低到高替換(非空的)。

FIFO Page Replacement Algorithm

​ 比較簡單,就是維護一個LinkedList,按頁面進入內存的順序將這寫頁面鏈接起來,每次替換的時候替換掉最先進入到內存的頁面,這種雖然簡單但並不實用。

Second Chance Page Replacement Algorithm

在這里插入圖片描述

​ 基於前面的FIFO Page Replacement Algorithm,A頁面是最先進入到內存的頁面,當需要替換頁面的時候找到A,然后檢查A的Referenced位,如果被置1,則將A放到隊尾並將Referenced清0,若此時的隊頭是B,且B的R位沒有被置則將其替換。

​ 等到再次輪到A的時候,發現A的R位沒有被置就說明在這段時間里A沒有被訪問過。這就相當於給了A第二次機會,所以叫Second Chance Page Replacement Algorithm

The Clock Page ReplacementAlgorithm

在這里插入圖片描述

​ 用一個指針指向一個頁面,當發生缺頁需要替換的時候先判斷指針指向的頁的R位是否為1,如果為1則清0,將指針挪到下一個頁面上,再判斷如果為1繼續清0挪指針呢,如果為0則將其替換。不同於Second Chance的是沒有維護一個以時間為標准的隊列,但也給了第二次機會。

Least Recently Used(LRU)

​ 這個算法是每次替換的都是很長時間未被使用的頁面,一種可能的實現方法就是維護一個鏈表,但每次訪問內存都要更新這個鏈表開銷過大。還有一種方法上就是給page table加一項count,每次訪問這個頁面就給count++,通過這個count來表示這個頁面被訪問的次數。

Simulating LRU in Software (1)

在這里插入圖片描述

​ 一個數組,當訪問頁面x的時候,將第x行全部置為1,第x列全部置為0,按此順序模擬0、1、2、3、2、1、0、3、2、3,可以觀察到到d圖時第0行已經全部變為0,說明當一個頁面很久不被訪問的時候會由於其他頁面被訪問而將其所在行的“1”一列一列的全部置為0,由此可以根據某個頁面所在行的大小判斷是否替換這個頁面。

​ 可能會有這個疑問:如果訪問完頁面a,然后一直訪問頁面b,那么多次訪問過b后,a也是很久沒有訪問,但其所在行加起來還是很大。這個屬於理解錯誤,如果一直訪問同一個頁面那根本就不用用到頁面替換算法啊,頁面替換是當要訪的頁面不在內存中產生缺頁的時候才用的,一直訪問同一個頁面那最多發生一次頁面替換,之后這個頁面肯定已經存在與內存中了。

Simulating LRU in Software (2)

在這里插入圖片描述

​ 在第一個時間里針對0-5的頁面的R位是101011,在下面第一個列圖中表示出來,表示在這段時間里頁面0、2、4、5被訪問,下一個周期的訪問情況為110010,將前面的記錄情況向右平移一位,將最新的加到最前面。這樣五個周期下來,(e)圖表示了這五個周期里這6個頁面被訪問的情況。

​ 如果把每個頁面的bit pattern當作一個二進制數來看,這個數越大就說明這個頁面最近被訪問的越多,每次最近一個周期被訪問的情況被放到最前面,表示某次被訪問的情況是隨着時間的推移,它的權重也慢慢降低的。

The Working Set Page Replacement Algorithm

​ 工作集:一個進程當前正在使用的頁面的集合稱為它的工作集。設集合w(k,t),在任一時刻t,都存在一個集合w,它包含所有最近k次內存訪問所訪問的頁面。這個集合w(k,t)就叫工作集。

在這里插入圖片描述

橫軸為k

​ 現在來看一個基於工作集的頁面替換算法,基本思路就是:找出一個不在工作集中的頁面並替換掉它。

在這里插入圖片描述

​ 掃描所有頁面檢查R位,如果為1,則說明這次缺頁中斷發生的時候該頁面正在被使用,所以可以將上次使用的時間切換為當前的實際時間,這個頁面在當前的時鍾滴答周期中被訪問過,那么它就應該出現在工作集中,並且不應該被刪除。

​ 如果R為0,且生存時間(即當前實際運行時間減去上次使用時間)大於x,那就說明已經有超過x的時間沒有使用這個頁面了,那它就不應該出現在工作集里,所以將其移除。

​ 如果R為0,且生存時間小於x,那就說明x時間段內這個頁面至少使用過一次,但是要記錄生存時間最長的頁面,也就是“上次使用時間”最小的頁面,也就是站在現在這個時間使用最早的頁面。如果掃描完整個頁表卻沒有一個合適的被淘汰的頁面,那就淘汰生存時間最長的頁面。

WSClock Page Replacement Algorithm

​ 當缺頁中斷發生后,需要掃描整個頁表才能確定淘汰的頁面,因此基本的工作集算法是比較費時的。有一種基於時鍾算法的改進算法,並且使用了工作集信息,成為WSClock(工作集時鍾)算法。

​ 與時鍾算法一樣,所需的數據結構是一個以頁框為元素的循環表。最初,該表是空的。當裝入第一個頁面后,把它加入到該表中。隨着更多的頁面的加入,他們形成一個環。每個表項包含來自基本工作集算法的上次使用時間,以及R位(已標明)和M位(未標明)。

在這里插入圖片描述

​ 與時鍾算法一樣,每次缺頁中斷的時候,首先檢查指針指向的頁面。如果R位為1,則該頁面在當前的時鍾滴答中被使用過,則不適合淘汰,將其置0,指針指向下一個頁面。並重復該算法。

​ 如果R=0,當頁面的生存時間大於x並且該頁面是干凈的(干凈,個人理解就是沒有修改過),他就不在工作集中,並且在磁盤上有一個有效的副本。申請此框,並把新頁面放在其中。如果此頁面被修改過就不能立即申請頁框,因為這個頁面在磁盤上沒有有效的副本。為了避免由於調度寫磁盤操作引起的進程切換,指針繼續向前走,算法繼續對下一個頁面操作。比較,有可能存在一個舊的且干凈的頁面可以立即使用。

頁面置換算法小結

算法 注釋
最優算法 不可實現,但可以用作基准
NRU(最近未使用)算法 LRU的很粗糙的近似
FIFO(先進先出)算法 可能拋棄重要頁面
第二次機會算法 比FIFO有較大改善
時鍾算法 現實的
LRU(最近最少使用)算法 很優秀,但很難實現
NFU(最不經常使用)算法 LRU的相對粗略的近似
老化算法 非常近似LRU的有效算法
工作集算法 實現起來開銷很大
工作集時鍾算法 好的有效算法

Modeling Page Replacement algorithms

在這里插入圖片描述

​ (a)圖是FIFO with 3 page frames

​ (b)圖是FIFO with 4 page frames

​ 如圖,橫軸上0、1、2、3、0、1、4、0、1、2、3、4是頁面的訪問順序,豎軸是已經存在的物理的頁,(a)圖中,先訪問第0頁,內存中沒有,所以產生缺頁中斷,最下面用P標識,類似於一個堆棧,每當訪問一個新的頁面就向下壓棧,訪問第1頁,內存中也沒有,向下壓棧,產生缺頁中斷,用P標識,以此類推,一致向下壓棧,最下面的會被擠出去......當8次訪問第0頁時,內存中已經存在第0頁,所以不會產生缺頁中斷。

​ (b)圖同理(a)圖,但不同的是b圖中有4個物理的頁,通過觀察發現,(a)圖中三個物理的頁產生了9次缺頁中斷,而(b)圖中4個物理的頁卻產生了10次缺頁中斷。事實並沒有像預想的一樣物理的頁越多產生的缺頁中斷越少。這就叫Belady's Anomaly。

​ 要避免Belady's Anomaly的產生,就要保證物理頁多的里面放入的內容是物理頁少的里面內容的超集(也就是物理頁少的里面的內容是物理頁多的里面的內容的子集),這樣,物理頁越多產生的缺頁就越少。圖中的FIFO算法很明顯並不能保證這個前提。例如第8次訪問頁面a圖里是4、1、0,b圖里是0、4、3、2.

Stack Algorithm

​ 要保證上述的前提,引入了stack算法

在這里插入圖片描述

​ 前面的Reference string是訪問頁,下面的8個框是可以存放的堆棧頁,上面四個實框是真正的物理頁,每次訪問一個頁面的時候就往里面壓棧,到第5次訪問第5頁的時候相當於把0從物理頁擠出去了,但還存在於堆棧頁中,當第8次訪問第3頁時,3還在里面,就把堆棧中的3提前,不產生缺頁中斷,然后繼續類推,到第14次訪問第5頁的時候,5在堆棧頁中,但已經出了物理頁,所以會產生缺頁中斷,但還是同樣的將5提前,原來5上面的壓棧壓下去。下面的P表示產生了缺頁。Distance string表示的是當前訪問的頁在上次訪問內存后在堆棧中的第幾個,比如第14次訪問的第5頁,在第13次訪問完后,第5頁在5個,所以第14次的Distance string就等於5,如果上次訪問內存后堆棧頁中沒有這次訪問的頁就將Distance string等於無窮。

Probability density function

在這里插入圖片描述

pdf表示概率密度函數,橫軸為distance string,縱軸表示等於這個distance string的有多少個

The Distance String

在這里插入圖片描述

​ 用distance string計算頁面出錯率。左邊的C1就表示distance string等於1的有幾個,C2同理表示distance string等於2的有幾個。右邊的F1表示C2+C3+...+C無窮,同理F2 = C3+C4+...+C無窮。

​ 因此可以看出F1表示當有一個物理頁時候的缺頁次數,F2表示當有2個物理頁時候的缺頁次數。因為F1表示的是C2到C無窮的累加和,而C2又表示distance string=2時候的個數,distance string=2的就表示當前訪問的頁在堆棧頁的第二個,如果物理頁只有一個那就說明不在物理頁中,即會產生缺頁,C3、C4......C無窮類似。即Fx表示當有x個物理頁時候的缺頁次數。

Segmentation

分段和分頁的一些對比

在這里插入圖片描述

Implementation of Pure Segmentation

在這里插入圖片描述

Segmentation with Paging:MULTICS

​ 段頁式,在段里分頁。前面分頁是一個進程一個頁表,現在這種分段是一個段一個頁表。

​ 段的描述字descriptor的結構如圖右所示,18個bit位的Main memory address of the page table,用來表示這個段的頁表在內存中的地址;9個bit位的Segment length表示段的長度,以頁為單位,就是這個段有多少個頁;1個bit位的Page size,表示頁的大小,1024個或64個words;還有表示段是否啟動分頁的位,如果沒啟動就是純分段,啟動了就是段頁式。

在這里插入圖片描述

​ 上圖是一個34個bit位的虛擬地址,根據18個bit的段號去查表(就是上面的上面那個圖的最左邊那個表),找到段的頁表,根據后面6個bit的頁號,在頁表中找到具體的物理頁的位置(頁幀),最后根據10個bit的頁內偏移就可以找到真正的物理地址。

​ 為了加速查找,同樣引入了TLB。

在這里插入圖片描述

​ TLB中Segment number和Virtual page配合可以找到Page frame,Protection位表示讀寫權限,Age表示老化程度,因為TLB中的項是有限的,當需要淘汰掉某些項的時候,就根據項的老化程度,越大說明在TLB中時間越久。is this entry used表示這個項在不在內存里面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM