切換語言為:簡體
作業系統中的重要角色--記憶體管理

作業系統中的重要角色--記憶體管理

  • 爱糖宝
  • 2024-06-07
  • 2085
  • 0
  • 0

在開發工作中,雖然CPU,記憶體和硬碟都是必不可少的硬體,不過,程式設計中,我們常常受到困擾的往往是記憶體相關的bug(程式設計中遇到CPU和硬碟相關的bug極少)。

這是因為我們的程式和資料雖然是存放在硬碟上的,但是執行時,CPU並不是直接從硬碟載入程式和資料的。
直接從硬碟讀取指令非常慢,會成為整個系統的嚴重瓶頸,因此,程式及其資料首先被複制到記憶體(比硬碟驅動器小,但速度快得多)中,CPU從記憶體讀取指令速度會快很多。

記憶體可以看作是一長串單元,每個單元都包含一些二進制資料,並標有一個稱為儲存器地址的數字。
記憶體地址的範圍從0到N,取決於系統中可用的主記憶體量。
程式使用的地址範圍稱為地址空間

如下圖,兩個載入到記憶體空間中的程式Program-1Program-2
它們分別佔用了記憶體地址0~25~8的位置。
作業系統中的重要角色--記憶體管理

1. 早期的記憶體管理

在作業系統的早期,程式可以直接訪問整個主儲存器,如何管理記憶體是程式設計師的工作之一。
當時編寫軟體的一大挑戰性就在於開發人員需要設計一種管理RAM訪問的好方法,並確保整個程式不會溢位可用記憶體。

後來,隨著多工處理的出現,當多個程式可以在同一臺計算機上執行時,記憶體管理變得越來越棘手。
程式設計師不得不面對自己管理記憶體帶來的主要問題:

  1. 記憶體佈局問題:位於RAM中的第一個程式之後的程式將有一定量的地址空間偏移,不再是初始範圍0到N(比如上面圖片中的Program-2)。多個程式載入記憶體時,極大增加管理難度。

  2. 記憶體碎片問題:當程式或資料在記憶體中來回移動時,可用空間會被碎片化為越來越小的塊。這將使它更難找到可用的空間來載入新的程式和記憶體中的資料

  3. 安全性問題:如果程式A不小心覆蓋了程式B的記憶體怎麼辦?或者,更糟糕的是:如果它故意從另一個程式中讀取敏感資料,如密碼或信用卡資訊,該怎麼辦?

因此,對於20世紀60年代早期的硬體架構師來說,急需一種自動化的記憶體管理形式,這樣可以顯著簡化程式設計並解決更關鍵的記憶體保護問題。
最後,他們想出了今天被稱為虛擬記憶體的東西。

2. 虛擬記憶體管理

虛擬記憶體中,程式不能直接訪問物理RAM。相反,它與一個名為虛擬記憶體的空間互動。
作業系統與CPU一起提供這樣的虛擬地址空間,並遲早將其轉換為實體地址空間。

每個記憶體訪問都是透過一個虛擬地址來執行的,該地址並不指向記憶體中的實際物理位置。
程式總是讀取或寫入虛擬地址,它完全不知道底層硬體中發生了什麼。

比如,仍然是上面的Program-1Program-2,對於這兩個程式來說,開發人員可以假定它們的地址都是從0開始。
而它們實際在實體記憶體中的位置開發人員不用關心,交給作業系統來負責就可以了。
作業系統中的重要角色--記憶體管理

2.1. 虛擬記憶體的優勢

從上面的圖中,我們可以看出虛擬記憶體的明顯好處:

  1. 每個程式都有一個從0開始的虛擬地址空間,大大簡化了程式設計師的負擔,不再需要手動跟蹤記憶體偏移

  2. 虛擬記憶體總是連續的,即使底層的實體記憶體不是連續的。作業系統完成了將可用記憶體塊聚集到一個單一的、統一的虛擬記憶體塊中的艱鉅任務

  3. 虛擬記憶體機制還解決了記憶體有限的問題,開發時給人一種印象,不用擔心實體記憶體還有多少(當然實際執行時,如果記憶體不足,作業系統會提示錯誤)

  4. 虛擬記憶體保證了安全性:作業系統會保證程式A不能讀取或寫入分配給程式B的虛擬記憶體

2.2. 虛擬記憶體管理的核心結構

虛擬記憶體機制需要一個位置來儲存虛擬地址和實體地址之間的對映。
也就是說,給定虛擬地址X,系統必須能夠找到對應的實體地址Y
但是,不能將這樣的資訊儲存為1:1關係,否則就需要一個與整個實體記憶體一樣大的虛擬地址庫。

現代虛擬記憶體實現透過將虛擬記憶體實體記憶體解釋為一長串固定大小的小塊來克服這個問題(以及許多其他問題)。
虛擬記憶體中將這個塊稱為實體記憶體中將這個塊稱為

在CPU中有一個硬體元件叫做記憶體管理單元(MMU),它將之間的對映資訊儲存在一個稱為頁表的特殊數據結構中。
頁表中每一行都包含一個索引及其對應的索引,每個正在執行的程式在MMU中都有一個自己的頁表,
如下圖所示:

作業系統中的重要角色--記憶體管理
程式Program-1佔用3個記憶體頁,編號為0~2,透過MMU頁表對映到實體記憶體中幀3,4,8

虛擬記憶體的虛擬地址由兩部分組成:

  1. 一個頁面索引,告訴虛擬地址所屬的頁面

  2. 幀偏移量,表示幀內實體地址的位置

2.3. page faults是什麼

當程式訪問當前未對映到物理幀的虛擬地址時,會發生頁面錯誤page faults)。
更具體地說,當頁面存在於程式的頁面表中,但指向實體記憶體中不存在或尚未可用的幀時,就會發生頁面錯誤
比如:
作業系統中的重要角色--記憶體管理
MMU檢測到頁面錯誤會將訊息反饋到作業系統,作業系統將盡最大努力在實體記憶體中找到用於對映的幀。
大多數情況下,這是一個簡單的操作,除非系統記憶體不足。

2.4. 記憶體分頁(paging)是什麼

分頁paging)是另一個記憶體管理技巧:作業系統將一些頁面移動到硬碟驅動器,以便在沒有更多實體記憶體可用時為其他程式或資料騰出空間。
分頁有時也被稱為交換swapping),交換是將整個程序移動到磁碟上。

分頁給程式一種無限可用記憶體的錯覺,作業系統樂觀地允許虛擬記憶體地址空間大於實體記憶體地址空間,知道資料可以在需要時移入和移出硬碟驅動器。
有些系統(如Windows)使用一個特殊的檔案,稱為分頁檔案。其他作業系統(例如Linux)有一個稱為交換區域的專用硬碟分割槽。

不過,需要注意的是,硬碟驅動器比主記憶體慢得多。
因此,當發生頁面錯誤並且頁面臨時移動到硬碟驅動器時,作業系統必須從緩慢的介質中讀取資料並將其移回記憶體,從而導致延遲。
總而言之,更少的分頁意味著系統可以更有效地執行。

2.5. 記憶體顛簸(Thrashing)是什麼

當系統在分頁上花費的時間多於執行應用程式的時間時,就會發生抖動,這是由不斷的頁面錯誤流觸發的。
這是一種極端的情況,比如你執行了太多的程式,佔用了整個記憶體以及在硬碟上的分頁區域,
這時就容易發生頁面錯誤,作業系統爲了跟上大量的頁面錯誤請求,不斷地在硬碟驅動器和實體記憶體之間移動資料,使系統陷入停頓。

解決這個問題可以透過增加記憶體的容量,或者減少正在執行的程式的數量,或再次透過調整交換檔案的大小來避免抖動。

2.6. 儲存保護

虛擬記憶體還提供了跨執行應用程式的安全性,比如你的瀏覽器無法窺視你的文字編輯器的虛擬記憶體,反之亦然。
記憶體保護的主要目的是防止程序訪問不屬於它的記憶體。

記憶體保護機制通常由MMU及其管理的頁表提供。當一個程式試圖訪問一部分它不擁有的虛擬記憶體時,就會觸發一個無效的頁面錯誤。
MMU和作業系統捕獲訊號並引發故障條件,稱為分段錯誤(就是耳熟能詳的segmentation fault),作業系統通常會終止程式作為響應。

3. 總結

總之,虛擬記憶體為我們解決了很多問題,也簡化了簡化了程式設計師的工作,是目前主流的記憶體管理方式。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.