天天看點

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

作業系統的兩個角色分别是魔術師和管理者,在管理者這個角色中,除了CPU之外,記憶體是作業系統要管理的另外一個重要資源。記憶體管理需要達到兩個目标:一是位址保護,即一個程式不能通路另一個程式的位址空間。二是位址獨立,即程式發出的位址應該與實體主存位址無關。這兩個目标就是衡量一個記憶體管理系統是否完善的标準,它是所有記憶體管理系統必須提供的基本抽象。

  作業系統的兩個角色分别是魔術師和管理者,在管理者這個角色中,除了CPU之外,記憶體是作業系統要管理的另外一個重要資源。記憶體管理需要達到兩個目标:一是位址保護,即一個程式不能通路另一個程式的位址空間。二是位址獨立,即程式發出的位址應該與實體主存位址無關。這兩個目标就是衡量一個記憶體管理系統是否完善的标準,它是所有記憶體管理系統必須提供的基本抽象。

一、記憶體管理二三事

1.1 記憶體管理的目标

  (1)位址保護:一個程式不能通路另一個程式位址空間。

  (2)位址獨立:程式發出的位址應該與實體主存位址無關。

  這兩個目标是衡量一個記憶體管理系統是否完善的标準,它是所有記憶體管理系統必須提供的基本抽象。 

1.2 虛拟記憶體的概念

  虛拟記憶體的中心思想是将實體主存擴大到便宜、大容量的磁盤上,即将磁盤空間看做主存空間的一部分。可以了解為是将書桌上的比較老的檔案先暫時收到抽屜裡,用空出來的地方來攤開新的檔案。在計算機中,展現在在記憶體容量不足時将不經常通路的記憶體空間中的資料寫入硬碟,以增加“賬面上”可用記憶體容量的手段(想想我們的記憶體和硬碟容量對比就知道了)。

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  但是,如果在書桌和抽屜之間頻繁進行檔案的交換,工作效率肯定會下降。如果每次要看一份檔案都要先收拾書桌再到抽屜裡面拿的話,那工作根本就無法進行了。

  虛拟記憶體的優點在于除了讓程式員感覺到記憶體容量大大增加之外,還讓程式員感覺到記憶體速度也增快了。

  虛拟記憶體也有同樣的缺點:硬碟的容量比記憶體大,但也隻是相對的,速度卻非常緩慢,如果和硬碟之間的資料交換過于頻繁,處理速度就會下降,表面上看起來就像卡住了一樣,這種現象稱為抖動(Thrushing)。相信很多人都有過計算機停止響應的經曆,而造成當機的主要原因之一就是抖動。

二、基本記憶體管理

2.1 單道程式設計的記憶體管理

  在單道程式設計環境下,整個記憶體裡面隻有兩個程式:一個是使用者程式,另一個是作業系統。

  由于隻有一個使用者程式,而作業系統所占用的記憶體空間是恒定的,是以我們可以将使用者程式總是加載到同一個記憶體位址上,即使用者程式永遠從同一個地方開始執行。

  這樣,使用者程式裡面的位址都可以事先計算出來,即在程式運作之前就計算出所有的實體位址。這種在運作前即将實體位址計算好的方式叫做靜态位址翻譯。下面看看此方式如何達到兩個目标。

  (1)位址獨立:使用者在編寫程式時無需考慮具體的實體記憶體,使用者程式始終都被加載到同一個實體位址上。

  (2)位址保護:整個系統裡面隻有一個使用者程式,是以,固定位址的記憶體管理因為隻運作一個使用者程式而達到位址保護。

2.2 多道程式設計的記憶體管理

  在多道程式設計環境下,無法将程式總是加到固定的記憶體位址上,也就是無法使用靜态位址翻譯。是以,必須在程式加載完畢之後才能計算實體位址,也就是在程式運作時進行位址翻譯,這種翻譯稱為動态位址翻譯。

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  多道程式設計環境下的内管管理政策有兩種:

  (1)固定分區

  顧名思義,固定分區管理就是講記憶體分為固定的幾個區域,每個區域大小固定。最下面的分區為OS占用,其他分區由使用者程式使用。分區大小通常各不相同,當需要加載程式時,選擇一個目前閑置且容量足夠大的分區進行加載,如下圖所示,這是一種共享隊列的固定分區(多個使用者程式排在一個共同的隊列裡面等待分區):

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  由于程式大小和分區大小不一定比對,有可能形成一個小程式占用一個大分區的情況,進而造成記憶體裡雖然有小分區閑置但無法加載大程式的情況。這時,我們就想到也許可以采用多個隊列,給每個分區一個隊列,程式按照大小排在相應的隊列裡,如下圖所示,這時一種分開隊列的固定分區:

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  上圖這種方式也有缺點:如果還有空閑分區,但等待的程式不在該分區的等待隊列上,就将造成有空間而不能運作程式的尴尬。

  (2)非固定分區

  非固定分區的思想在于除了劃分給OS的空間之外,其餘的記憶體空間是作為一個整體存在的。當一個程式需要占用記憶體空間時,就在該片空間裡面分出一個大小剛剛滿足程式所需的空間。再來一個程式時,則在剩下的空間裡再這樣分出一塊來。在這種模式下,一個程式可以加載到任何地方,也可以和實體記憶體一樣大。

  例如,一開始記憶體中隻有OS,這時候程序A來了,于是分出一片與程序A大小一樣的記憶體空間;随後,程序B來了,于是在程序A之上分出一片給程序B;然後程序C來了,就在程序B上面再分出一片給C。如此,程序A、B和C的起始位址都不是固定的,如下圖所示:

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  仔細一看,這種方式存在一個重大問題:每個程式像疊羅漢一樣累計,如果程式B在成型過程中需要更多空間怎麼辦?(例如在實際程式中,很多遞歸嵌套函數調用的時候回造成棧空間的增長)是以,我們可以想到可以再一開始的時候給程式配置設定空間時就配置設定足夠大的空間,留有一片閑置空間供程式增長使用,如下圖所示:

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  不過,OS怎麼知道應該配置設定多少空間給一個程式呢?配置設定多了,就是浪費;而配置設定少了,則可能造成程式無法繼續執行。

  是以,可以在空間不夠時,給程式換一個空間,這種方式将程式倒到磁盤上,再加載到記憶體中,被稱為交換(swap)。但是,如果在交換模式下程式的增長超過了實體記憶體,就不能再交換了。此時,可以将程式按照功能分成一段一段功能相對完整的單元,一個單元執行完成後再執行下一個單元,這就是重疊(overlay)。

  但是,交換記憶體管理這種方式存在兩個重要問題:

  (1)空間浪費:随着程式在記憶體與磁盤間的交換,記憶體将變得越來越碎片化,即記憶體将被不同程式分割成尺寸大小無法使用的小片空間。

  (2)程式大小受限:這有兩層意思,一是指空間增長效率低下(由于磁盤操作耗時,交換出去再找一片更大的空間來增長程式空間的做法效率非常低),二是空間增長存在天花闆限制(單一程式不能超過實體記憶體空間)。

2.3 閑置空間管理

  在管理記憶體的時候,OS需要知道記憶體空間有多少空閑?這就必須跟蹤記憶體的使用,跟蹤的辦法有兩種:

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

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  (2)将配置設定單元按照是否閑置連結起來,這種方法稱為連結清單表示法。如上圖所示的的位圖所表示的記憶體配置設定狀态,使用連結清單來表示的話則會如下圖所示:

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

  在連結清單表示下,尋找一個給定大小的閑置空間意味着找到一個類型為H的連結清單項,其大小大于或等于給定的目标值。不過,掃描連結清單速度通常較慢。

參考資料

作業系統核心原理-5.記憶體管理(上):基本記憶體管理

鄒恒明,《作業系統之哲學原理》,機械工業出版社

作者:周旭龍

出處:http://edisonchou.cnblogs.com

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結。

繼續閱讀