1. 程式人生 > >作業系統對記憶體管理

作業系統對記憶體管理

為什麼叫記憶體的抽象?

如果看過設計模式的人可能會知道,設計模式中提到最多的概念之一就是抽象,純虛的基類作為介面就是對各種派生類物件的抽象。呼叫介面的使用者,並不知道內部如何實現,因此內部實現的方法可能也有多種。地址空間也可以這樣理解,32位機上,建立程序時作業系統為程序分配4GB的獨立地址空間,使用者可以使用這4GB的獨立地址空間。但是,反過來一想,給每個程序都分配4GB地址空間,對於8GB記憶體的計算機而言豈不也就能同時執行兩個程序。對於現代計算機而言,這顯然是不可能的。所以實際上,使用者能使用的4GB地址空間並不是對應實體記憶體的4GB,具體怎麼實現被封裝了,所以叫記憶體抽象。

多道程式實現

現代作業系統能夠同時執行多個程式,程式被執行時,需要佔用記憶體的一塊空間,如果同時執行的程式太多,實體記憶體裝不下了怎麼辦?因此出現了兩種技術,交換技術和虛擬記憶體。

交換技術

交換技術:就是指當記憶體滿了以後,就將一個程式從記憶體換出,將另一個程式放入記憶體,換出的記憶體資料儲存在硬碟上,當該程式再次被換入的時候,就將硬碟上的資料拷貝到記憶體。

如下圖,藍色區域表示空閒的記憶體,綠色區域表示被某個程序佔用的記憶體。剛開始裝入A程序,然後裝入B程序,再裝入C程序。對於程序B而言假設其地址空間為0x0000-0xFFFF,對於其地址0x0000而言,對應的實體地址肯定不是0x0000,那應該是程序A的首地址。所以如果程序B要訪問其首地址0x0000,就必須加上一個偏移量,而這樣偏移量儲存在一個基址暫存器中,除了基址暫存器還有一個界限暫存器防止訪問越界。

再接著上面的說,如果這時候來了一個程序D,剩餘的記憶體放不下程序D了,這時候可以選擇將程序B交換出去,將程序B的資料儲存到硬碟上,將程序D裝入記憶體執行,如果CPU重新排程到程序B然後再採用同樣的方式將某個程序交換出去,儲存到硬碟上,把程序B裝入記憶體中,這樣的過程就叫交換技術。

記憶體交換

虛擬記憶體

交換技術似乎解決了多道程式執行的問題,但是實際上如果每次交換一整個程序的資料,CPU需要花費數秒的時間來處理,這顯然是不能被容忍的。因此,需要提出虛擬記憶體的概念。

虛擬記憶體:作業系統為了管理記憶體,給每個程序都分配獨立的地址空間,對32位的系統而言,這個空間的大小是4GB。這4GB並不是實際的實體記憶體,實際上並不存在,因此有虛擬記憶體這一名稱。

虛擬地址空間的地址稱為邏輯地址,實際實體記憶體(就是記憶體條的大小)的地址空間稱為實體地址。虛擬地址空間被分割成多個大小相同的頁面(比如4k為一個頁面),實體地址空間被分割成同樣大小的頁框。虛擬地址的頁面通過一個頁表對映實體記憶體的頁框,頁表中儲存著兩者的對應關係。邏輯地址是CPU使用的地址,當程序要訪問該程序地址空間裡的某個地址時時候,將該地址的值傳遞給CPU,CPU訪問該地址時,會經過MMU將邏輯地址轉換為實體地址,之前說的頁表就儲存在MMU中,作業系統為每個程序都維護一個頁表。

MMU

說了這麼多,我們還是不清楚為什麼用虛擬記憶體就能實現多個程式同時執行,並且切換效能很高呢?

我們剛剛講了,MMU把虛擬地址空間的頁表和實體地址空間的頁框關聯起來了,如果頁表中所有的資料都在頁框中有對應項,那虛擬地址就沒有任何意義了。實際上,程式執行的時候只需要部分資料存在記憶體中就可以了,因此只有部分頁面和頁框有對應值,其餘的頁表的資料儲存在硬碟一塊固定的地方(在Linux裡叫swap分割槽,window裡儲存在C盤裡)。當訪問到某個頁面在實體記憶體中沒有對應的頁框時就會發生缺頁中斷,這時候作業系統就將該頁面儲存在硬碟中的資料拷貝到實體記憶體中,並更新頁表建立該頁面和對應頁框之間的對映關係。

這樣做就實現了每次交換的代價很小,但是實體地址空間還是可能不夠用,因此作業系統交換一些資料進實體記憶體的時候,也會從實體記憶體中移除部分頁框資料到硬碟上,那到底該移出誰呢?這就涉及到頁面交換演算法了。

Linux記憶體管理

以Linux系統為例談談作業系統對記憶體的管理,一點皮毛,用於梳理自己的思路,使得面試的時候能夠思路更清晰。

前面講了程序具有獨立的地址空間,對於32位的系統而言,該地址空間的大小是4GB。Linux將這4GB的地址空間分為兩部分,一個是使用者地址空間,一個是核心地址空間。核心地址空間的地址範圍範圍為3G到4G,使用者地址空間的地址範圍為0G到3G。這裡所講的0G到4G都是虛擬地址,也稱為邏輯地址。

Linux對核心空間和使用者空間是分別管理的,因為程序要麼執行在使用者態,要麼執行在核心態,程序通過系統呼叫陷入核心態。

這裡寫圖片描述
(借用網上一張圖片說明一下,侵刪)

核心空間

核心空間的邏輯地址範圍在3GB到4GB,並且核心空間是線性對映到物理空間的。何為線性對映,舉例說明,核心空間邏輯地址0xc0000000對應的實體地址是0x00000000,邏輯地址0xc0000001對應的實體地址是0x00000001,也就是說邏輯地址到物理都減了一個0xc0000000的偏移量。如果1GB都是這樣對映的話,那麼核心空間能使用實體地址範圍在0x00000000到0x40000000之間,不能訪問所有的實體地址了。

為了解決這個問題,核心空間就將實體記憶體分為三個區:ZONE_DMA,ZONE_NORMAL,ZONE_HIHGEM。DMA區是用於一些特殊裝置的,我們不過多追究。主要討論高階記憶體(ZONE_HIHGEM),對於核心空間而言高於896M的空間稱為高階記憶體,低於896M的自然就可以稱為低端記憶體了,低端記憶體的範圍上,邏輯地址與實體地址是線性對映的。對於核心空間896M以上剩餘的128M是用來訪問高階記憶體的。這128M裡的頁面到物理頁框隨機對映的,和使用者空間的對映是一樣的。低端記憶體是自動永久對映的,高階記憶體可以永久對映也可以零時對映。

前面兩端主要將的是對頁表頁框的管理,後面再將如何分配記憶體,也就是如果核心需要一定大小的記憶體的時,在3GB到4GB的範圍裡取出拿一塊給它。核心空間分配記憶體可以按頁分配,採用alloc_pages()和free_pages()函式分配多個連續頁大小的記憶體,也可以通過kmalloc()分配指定大小的記憶體。

核心分配記憶體時很多時候都是分配固定大小的記憶體塊,比如為每一個程序維護的task_struct結構體等。頻繁分配這樣的小塊,很容易造成記憶體碎片,自然想到用記憶體池的方法來解決記憶體碎片的問題,只不過在Linux中給其取了一個更高大上的名字,叫快取記憶體cache與slab層。一個快取記憶體中有多個slab,分為三類:滿的,部分滿,和空的。每個slab就是一個連結串列,連結串列的每個節點就是一塊固定大小的記憶體。和記憶體池是一樣的。

使用者空間

看過作業系統書的人肯定看到過下面這樣圖。
這裡寫圖片描述

這張圖解釋了,一個程序將資料分為程式碼段,資料段,BSS段,堆和棧。實際上這些資料分享了0GB到3GB的地址範圍。Linux管理這些段採用分割槽的結構,為每一個段維護一個vm_area_struct的結構體。這些結構體中儲存了指向下一個指標因此形成了連結串列,還有另外一個指標使其構成紅黑樹,使用者快速查詢。

對於使用者空間不得不談到malloc函式,malloc函式是動態分配記憶體,記憶體來自使用者空間的堆區。作業系統通過連結串列的形式將堆區的空間貫穿起來,當需要動態分配記憶體時就去查詢該連結串列,找到空閒塊,如果堆區滿了,就呼叫sbrk函式擴大堆的範圍。
當分配記憶體時,作業系統去查詢該連結串列,找到一塊能容納下的地方放進去,將剩餘的返還給空閒表。如何找到這個容納的地方有出現了多種演算法:首次適配演算法,第二次首次適配,最佳適配演算法,最差適配演算法。這四個演算法你可以去細講差別,首次適配第一次找到第一個大於需要的地址空間的塊,每次都從表頭開始找,第二次著從上次找到的位置開始找,最佳適配找一個和需要大小最接近比需要的大的,最差每次早最大的。實際上對於程序內部堆的分配,頁可以採取同樣類似的辦法。具體可以去看malloc的原始碼。

另外還有一點很重要的是記憶體對映檔案,記憶體對映檔案通過mmap函式實現,將檔案對映到記憶體中,讀寫檔案通過操作指標就能實現。實際上,記憶體對映檔案並不是呼叫mmap的時候就將該檔案拷貝到記憶體中,而是建立邏輯地址到檔案地址之間的對映關係,但訪問這段記憶體的資料時還是引發缺頁中斷,然後將該頁的資料換到實體地址上。可以直接使用mmap實現程序間記憶體共享,XSI的記憶體共享實現的原理也是基於mmap,只是對映一種特殊檔案系統的檔案到記憶體中,該檔案不能通過read和write呼叫來訪問。

最後用一張圖來結束本篇文章
這裡寫圖片描述

如有錯誤歡迎指正!

相關推薦

作業系統記憶體管理

為什麼叫記憶體的抽象? 如果看過設計模式的人可能會知道,設計模式中提到最多的概念之一就是抽象,純虛的基類作為介面就是對各種派生類物件的抽象。呼叫介面的使用者,並不知道內部如何實現,因此內部實現的方法可能也有多種。地址空間也可以這樣理解,32位機上,建立程序時作

淺談作業系統記憶體管理

簡介     記憶體是計算機中最重要的資源之一,通常情況下,實體記憶體無法容納下所有的程序。雖然實體記憶體的增長現在達到了N個GB,但比實體記憶體增長還快的是程式,所以無論實體記憶體如何增長,都趕不上程式增長的速度,所以作業系統如何有效的管理記憶體便顯得尤為重要。本文講述作業系統對於記憶體的管理的過去和現在

2019年王道計算機考研作業系統筆記---記憶體管理

1. 名詞解釋 覆蓋:用於早期作業系統,打破了記憶體有限的侷限性,使得作業不必一次性調入記憶體 交換:把不需要用到的程序,暫時調離出記憶體 頁表:儲存頁號對應塊號的對映關係,一段連續的空間 段表:儲存

計算機作業系統_記憶體管理

記憶體管理 設計程式模擬記憶體的動態分割槽記憶體管理方法。記憶體空閒區使用空閒分割槽表進行管理,採用最先適應演算法從空閒分割槽表中尋找空閒區進行分配,記憶體回收時不考慮與相鄰空閒區的合併。 假定系統的記憶體共640K,初始狀態為作業系統本身佔用40K。 t1 時刻,為作業A、B、

作業系統概念-記憶體管理

為了實現段頁式管理,系統必須為每個作業或程序建立一張段表以管理記憶體分配與釋放、缺段處理、儲存保護相地址變換等。另外,由於一個段又被劃分成了若干頁,每個段又必須建立一張頁表以把段中的虛頁變換成記憶體中的實際頁面。顯然,與頁式管理時相同,頁表中也要有相應的實現缺頁中斷處理和頁面保護等功能的表項。另外,由於在段頁

作業系統記憶體管理-基本分段管理方式

引入分段儲存管理方式的目的: 主要是為了滿足使用者(程式設計師)在程式設計和使用上多方面的要求。 在分段儲存管理方式中,作業的地址空間被劃分為若干個段,每個段定義了一組邏輯資訊、 例如,有主程式段MAIN、子程式段X、資料段D及棧段S等(如下段表圖)。每個段都有自己的名字。

作業系統——虛擬記憶體管理

面試問題彙總: 1.邏輯地址、線性地址,實體地址,虛擬地址分別是什麼 實體地址,CPU地址匯流排傳來的地址,實體地址中很大一部分是留給記憶體條中的記憶體的 線性地址(Linear Address)也叫虛擬地址(virtual address)是邏輯地址到實體地址變換之間

作業系統記憶體管理機制

記憶體管理(Memory management)旨在為系統中所有的task提供穩定可靠的記憶體分配、釋放與保護的機制 不論是android 中的音訊系統、GUI系統、或者是Binder實現的機理等都與記憶體的管理是息息相關的。 虛擬記憶體 計算機出現的早期物理的記憶體普遍

第七章—記憶體管理【計算機作業系統

7.1 記憶體管理需要滿足哪些需求? 重定位、保護、共享、邏輯組織和物理組織。 7.2 為什麼需要重定位程序的能力? 通常情況下,並不能事先知道在某個程式執行期間會有哪個程式駐留在主存中。此外還希望通過提供一個巨大的就緒程序池,能夠把活動程序換入和換出主存,以便使處理器的利用率

現代作業系統:第三章 記憶體管理

作業系統的工作是將這個儲存體系抽象成為一個有用的模型並將管理這個抽象模型 作業系統中管理分層儲存體系的部分稱為儲存管理器。它的任務是有效的管理記憶體,即記錄哪些記憶體是正在使用的,哪些記憶體是空閒的,在程序需要時為其分配記憶體,在程序使用完成的時候為其釋放記憶體。 3.1 無儲存器的

作業系統記憶體管理

轉載:https://blog.csdn.net/BillCYJ/article/details/79039828 內容會持續更新,有錯誤的地方歡迎指正,謝謝! 記憶體管理 問題 1、什麼是區域性性原理? 時間上的區域性性:最近被訪問的頁在不久的將來還會被訪問,例如:迴圈語句; 空間上的

易學筆記-系統分析師考試-第3章 作業系統基本原理/3.3 記憶體管理/3.3.4 虛擬儲存管理

虛擬儲存管理 背景:固定式、分頁式、分段式儲存一個共同的特點是要求的儲存空間必須足夠大裝載入作業的全部資訊,但由於作業在執行過程中,作業中所有的記憶體不是一次全部使用的,甚至有些記憶體塊根本就不是使用,這樣就造成了記憶體資源的極度浪費 虛擬儲存工作過程:當作業載入到記憶體時

易學筆記-系統分析師考試-第3章 作業系統基本原理/3.3 記憶體管理/3.3.3 段頁式管理

分頁式儲存管理 概念:為了避免分割槽式管理產生儲存碎片和管理複雜的問題,分頁式管理把作業的邏輯地址劃分成若干個相等的區域(稱為頁),記憶體空間也劃分成若干個與頁長度相等的區域(也稱為頁幀或塊),然後把頁裝載到頁幀中 特點 頁幀可以是連續的,也可以是不連續的

易學筆記-系統分析師考試-第3章 作業系統基本原理/3.3 記憶體管理/3.3.2 分割槽儲存管理

記憶體儲存管理方式分類 分割槽儲存管理方式 分頁式儲存管理方式 分段式儲存管理方式 虛擬儲存器 分割槽儲存管理方式 固定分割槽 分割槽方法:在裝入作業前,記憶體被操作管理員分為N個區,分割槽大小和分割槽數量不可以修改

易學筆記-系統分析師考試-第3章 作業系統基本原理/3.3 記憶體管理/3.3.1 地址變換

幾種程式 源程式:使用者用開發語言編寫的程式 編譯程式(彙編程式):專門編譯源程式的程式 目標程式:編譯後的程式 地址 邏輯地址 概念:指的是目標程式使用的地址,也稱為相對地址或者虛擬地址 格式:一般以0為基地址

《現代作業系統》閱讀筆記——記憶體管理

地址重定位 最開始的計算機沒有重定位,程式直接使用記憶體的實體地址 任然被微波爐,洗衣機等嵌入式裝置使用 缺點是一次只能執行一個程式,因為第二個程式地址起始位置會變動 靜態重定位

現代作業系統 第三章 記憶體管理 習題

Chapter03 第三章 記憶體管理 習題 知識點小記 當一個程序發生缺頁中斷的時候,程序會陷入核心態,執行以下操作: 1、檢查要訪問的虛擬地址是否合法 2、查詢/分配一個物理頁 3、填充物理頁內容(讀取磁碟,或者直接置0,或者啥也不幹) 4、建立對映關係(虛擬地址到實體

作業系統(10) -- 段頁結合的實際記憶體管理模型

前面說過使用者程式喜歡分段來管理記憶體,但是實際的實體記憶體更加傾向於分頁管理,因為這樣可以使記憶體的利用率最大化。作為作業系統,既要向上負責,又要向下負責。這一篇部落格主要談談使用者程式需要的段和實體記憶體需要的頁是如何結合到一起的。 虛擬記憶體 虛擬記憶體

作業系統概念總結筆記——第八章 記憶體管理

本章目標:1、詳細討論記憶體硬體的組織方法;2、討論各種記憶體管理技術,如分段、分頁;8.1 背景介紹快取記憶體: 由於CPU對暫存器的訪問速率快於對記憶體的訪問速率,導致在實際執行中,沒有資料完成正在進行的操作,CPU通常需要暫停(stall), 由於記憶體的頻繁訪問,這種

Nginx學習之路(六)NginX中的記憶體管理之---Nginx中的記憶體齊和記憶體分頁

Nginx由於極高的效能受到大家的追捧,而Nginx的高效能與它優秀的記憶體管理方式是分不開的,今天就來聊一聊Nginx中的記憶體對齊和記憶體分頁。先說下Nginx中的記憶體對齊,Nginx中的記憶體對齊機制是它高效能的關鍵因素之一,先說點基礎的東西,什麼是記憶體對齊呢? 記