操做系統核心原理-5.內存管理(上):基本內存管理

  操做系統的兩個角色分別是魔術師和管理者,在管理者這個角色中,除了CPU以外,內存是操做系統要管理的另一個重要資源。內存管理須要達到兩個目標:一是地址保護,即一個程序不能訪問另外一個程序的地址空間。二是地址獨立,即程序發出的地址應該與物理主存地址無關。這兩個目標就是衡量一個內存管理系統是否完善的標準,它是全部內存管理系統必須提供的基本抽象。程序員

1、內存管理二三事

1.1 內存管理的目標

  (1)地址保護:一個程序不能訪問另外一個程序地址空間。編程

  (2)地址獨立:程序發出的地址應該與物理主存地址無關。小程序

  這兩個目標是衡量一個內存管理系統是否完善的標準,它是全部內存管理系統必須提供的基本抽象。 函數

1.2 虛擬內存的概念

  虛擬內存的中心思想是將物理主存擴大到便宜、大容量的磁盤上,即將磁盤空間看作主存空間的一部分。能夠理解爲是將書桌上的比較老的文件先暫時收到抽屜裏,用空出來的地方來攤開新的文件。在計算機中,體如今在內存容量不足時將不常常訪問的內存空間中的數據寫入硬盤,以增長「帳面上」可用內存容量的手段(想一想咱們的內存和硬盤容量對比就知道了)。spa

desk

  可是,若是在書桌和抽屜之間頻繁進行文件的交換,工做效率確定會降低。若是每次要看一份文件都要先收拾書桌再到抽屜裏面拿的話,那工做根本就沒法進行了。操作系統

  虛擬內存的優勢在於除了讓程序員感受到內存容量大大增長以外,還讓程序員感受到內存速度也增快了。翻譯

  虛擬內存也有一樣的缺點:硬盤的容量比內存大,但也只是相對的,速度卻很是緩慢,若是和硬盤之間的數據交換過於頻繁,處理速度就會降低,表面上看起來就像卡住了同樣,這種現象稱爲抖動(Thrushing)。相信不少人都有過計算機中止響應的經歷,而形成死機的主要緣由之一就是抖動。blog

2、基本內存管理

2.1 單道編程的內存管理

  在單道編程環境下,整個內存裏面只有兩個程序:一個是用戶程序,另外一個是操做系統。遞歸

  因爲只有一個用戶程序,而操做系統所佔用的內存空間是恆定的,因此咱們能夠將用戶程序老是加載到同一個內存地址上,即用戶程序永遠從同一個地方開始執行隊列

  這樣,用戶程序裏面的地址均可以事先計算出來,即在程序運行以前就計算出全部的物理地址。這種在運行前即將物理地址計算好的方式叫作靜態地址翻譯。下面看看此方式如何達到兩個目標。

  (1)地址獨立:用戶在編寫程序時無需考慮具體的物理內存,用戶程序始終都被加載到同一個物理地址上。

  (2)地址保護:整個系統裏面只有一個用戶程序,所以,固定地址的內存管理由於只運行一個用戶程序而達到地址保護。

2.2 多道編程的內存管理

  在多道編程環境下,沒法將程序老是加到固定的內存地址上,也就是沒法使用靜態地址翻譯。所以,必須在程序加載完畢以後才能計算物理地址,也就是在程序運行時進行地址翻譯,這種翻譯稱爲動態地址翻譯

  多道編程環境下的內管管理策略有兩種:

  (1)固定分區

  顧名思義,固定分區管理就是講內存分爲固定的幾個區域,每一個區域大小固定。最下面的分區爲OS佔用,其餘分區由用戶程序使用。分區大小一般各不相同,當須要加載程序時,選擇一個當前閒置且容量足夠大的分區進行加載,以下圖所示,這是一種共享隊列的固定分區(多個用戶程序排在一個共同的隊列裏面等待分區):

  因爲程序大小和分區大小不必定匹配,有可能造成一個小程序佔用一個大分區的狀況,從而形成內存裏雖然有小分區閒置但沒法加載大程序的狀況。這時,咱們就想到也許能夠採用多個隊列,給每一個分區一個隊列,程序按照大小排在相應的隊列裏,以下圖所示,這時一種分開隊列的固定分區:

  上圖這種方式也有缺點:若是還有空閒分區,但等待的程序不在該分區的等待隊列上,就將形成有空間而不能運行程序的尷尬。

  (2)非固定分區

  非固定分區的思想在於除了劃分給OS的空間以外,其他的內存空間是做爲一個總體存在的。當一個程序須要佔用內存空間時,就在該片空間裏面分出一個大小剛剛知足程序所需的空間。再來一個程序時,則在剩下的空間裏再這樣分出一塊來。在這種模式下,一個程序能夠加載到任何地方,也能夠和物理內存同樣大。

  例如,一開始內存中只有OS,這時候進程A來了,因而分出一片與進程A大小同樣的內存空間;隨後,進程B來了,因而在進程A之上分出一片給進程B;而後進程C來了,就在進程B上面再分出一片給C。如此,進程A、B和C的起始地址都不是固定的,以下圖所示:

  仔細一看,這種方式存在一個重大問題:每一個程序像疊羅漢同樣累計,若是程序B在成型過程當中須要更多空間怎麼辦?(例如在實際程序中,不少遞歸嵌套函數調用的時候回形成棧空間的增加)所以,咱們能夠想到能夠再一開始的時候給程序分配空間時就分配足夠大的空間,留有一片閒置空間供程序增加使用,以下圖所示:

  不過,OS怎麼知道應該分配多少空間給一個程序呢?分配多了,就是浪費;而分配少了,則可能形成程序沒法繼續執行。

  所以,能夠在空間不夠時,給程序換一個空間,這種方式將程序倒到磁盤上,再加載到內存中,被稱爲交換swap)。可是,若是在交換模式下程序的增加超過了物理內存,就不能再交換了。此時,能夠將程序按照功能分紅一段一段功能相對完整的單元,一個單元執行完成後再執行下一個單元,這就是重疊overlay)。

  可是,交換內存管理這種方式存在兩個重要問題:

  (1)空間浪費:隨着程序在內存與磁盤間的交換,內存將變得愈來愈碎片化,即內存將被不一樣程序分割成尺寸大小沒法使用的小片空間。

  (2)程序大小受限:這有兩層意思,一是指空間增加效率低下(因爲磁盤操做耗時,交換出去再找一片更大的空間來增加程序空間的作法效率很是低),二是空間增加存在天花板限制(單一程序不能超過物理內存空間)。

2.3 閒置空間管理

  在管理內存的時候,OS須要知道內存空間有多少空閒?這就必須跟蹤內存的使用,跟蹤的辦法有兩種:

  (1)給每一個分配單元賦予一個字位,用來記錄該分配單元是否閒置。例如,字位取值爲0表示單元閒置,取值爲1則表示已被佔用,這種表示方法就是位圖表示法,以下圖所示:

  (2)將分配單元按照是否閒置連接起來,這種方法稱爲鏈表表示法。如上圖所示的的位圖所表示的內存分配狀態,使用鏈表來表示的話則會以下圖所示:

  在鏈表表示下,尋找一個給定大小的閒置空間意味着找到一個類型爲H的鏈表項,其大小大於或等於給定的目標值。不過,掃描鏈表速度一般較慢。

參考資料

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

 

相關文章
相關標籤/搜索