操作系統筆記-6-內存管理基礎

引言

花了一段時間才把之前的筆記整理了一部分,平時太忙也沒啥時間。今天開始整理內存管理部分的,內存管理部分大致分爲三部分筆記,第一部分就是本篇內存管理基礎,第二部分是虛擬內存,第三部分高速緩存。

一個程序在運行前,只是一個存儲在磁盤上的可執行的二進制文件,包括可執行指令和數據。當程序運行時,這個二進制文件會被加載到內存中,指令和數據在執行時會被cpu從內存中加載到寄存器中,然後執行,可能會把執行結果再次存入內存中。數據以何種形式存在內存,如果爲進程分配內存,進程退出如何回收,這個過程叫內存管理,接下來就詳細介紹這個過程

早期無存儲器抽象

無存儲器抽象內存訪問

用戶程序直接操作物理內存的地址,比如將位置爲1000的物理內存中的內容複製到REGISTER1

 MOV REGISTER1,1000
物理內存模型

在這裏插入圖片描述

  • a模型早期的主機和微機,很少使用
  • b模型多用於嵌入式系統
  • c模型早期用於個人計算機
    a、c模型有一個bug,用戶程序可能擦除操作系統內存,如果是這種無抽象的物理內存,同一時間只能運行一個進程。
多個程序運行-物理分塊內存
  • 原理:內存被分塊例如2kb一個塊,在CPU內部有特殊寄存器來記錄內存塊的保護key,當程序運行時,會有一個PSW與寄存器中的對應,當不屬於該內存塊的程序訪問時,PSW和寄存器中存的key將不一致,避免了程序訪問別的程序的內存。簡要示意圖如下
    在這裏插入圖片描述

  • 存在問題
    因爲程序還是利用絕對路徑訪問內存,所以存在不同應用程序訪問同一個內存塊的問題,導致程序崩潰,下圖的a和b加載到內存後內存結構爲c,但是a的第一句跳轉到24是沒問題,但是b第一句跳轉到28,但是內存地址28是程序a的。

    • IBM解決方案:靜態重定位
      當加載b程序到16384時,所有訪問地址都加上16384,比如JMP 28變成了JMP 16412,但是該方法不是一個通用的解決辦法。此外,還需要程序提供額外的信息來標識哪些是地址。

存儲抽象-地址空間

前邊已經知道了無存儲抽象,也就是直接使用物理內存的兩個缺點

  1. 哪怕只有一個應用程序運行,操作系統內存也可能會被偶然或惡意破壞
  2. 多應用程序併發運行困難
地址空間概念
  • 概念:地址空間並不侷限於存儲,它是一個抽象的概念,電話號碼是一個地址空間,ip也是,域名也是
  • 基地址和界限寄存器(動態重定位)
    • 使用基地址和界限寄存器時內存中進程的內存結構
      在這裏插入圖片描述
    • cpu訪問內存時,硬件會利用要訪問的地址+base,然後判斷是否大於base+limit的地址,如果大於那麼訪問就是越界的,產生錯誤並終止訪問。
      在這裏插入圖片描述
Swapping

如果內存足夠大到可以容納所有進程的代碼和數據,那麼地址空間加上硬件提供的動態重定位的方案或許已經可行,但是通常所有進程需要的內存超過存儲可以提供的範圍。

  • 標準Swapping
    • 原理:標準Swapping是通過換進程來重複利用內存空間,如下圖首先內存只有A進程,接着B、C進程被創建或者換入內存,緊接着D進程需要運行,A被換出;當A再次被調度時,將B換出給A騰空間,A再次進入內存。
      在這裏插入圖片描述
      但是A再次進入內存的時候,地址空間已經發生變化。所以,Swapping換入之後需要重新重定位,有兩種方式:
      1. 通過軟件在載入的時候重定位
      2. 通過硬件在運行的時候重定位(比較常用),基地址和界限寄存器就適用這種情況
    • 內存壓縮
      內存因爲進程的換入換出會產生一些內存空洞,這些內存空洞會導致內存浪費,因爲這些空洞連續內存空間大小不足以容納一個進程所需的空間。因此通過將所有進程佔用的空間全部向下移動,就有可能將小的空洞連成一大塊空閒內存。這種技術就叫內存壓縮
    • 進程內存大小分配問題
      1. 固定大小,如果進程大小是固定不會改變,操作系統只需簡單分配進程需要的大小
      2. 數據段可能增長,此時有四種解決方法
        1. 如果進程鄰近有空閒內存,分配給進程
        2. 如果進程鄰近是其他進程,那麼尋找一塊更大的空閒內存,將進程遷移過去
        3. 如果沒有更大的空閒內存,那麼嘗試將鄰近的進程交換出去
        4. 如果進程無法增長內存並且交換區已經滿了,那就掛起該進程直到有空閒內存(或者kill該進程)
      • 爲了提高內存分配的效率,滿足大部分進程內存都會增長的場景。(a)系統在分配內存時爲進程預留增長所需的空間;(b)如果進程有連個可增長的段,比如數據段和棧段,可以數據段從下往上分配,棧從上往下分配,如果內存不足時再增長內存。
        在這裏插入圖片描述
  • 頁面Swapping
    針對虛擬內存的,在下一部分詳細介紹
空閒內存管理
  • Bitmaps
    • 原理:將內存分塊成小的分配單元(可以是小到幾個字或者大到幾kb),然後用一個bitmap來記錄哪些塊已被使用,1代表使用,0代表空閒
      在這裏插入圖片描述
    • 關鍵:內存單元大小的選擇很關鍵,太小,bitmap太大,太大,會浪費有些空間
    • 缺點:當需要爲進程分配內存時,內存管理系統需要遍歷bitmap找出一段連續的空間,這個操作是很費時的
  • 空閒鏈表
    • 原理:用鏈表將以使用和未使用的內存連接起來,每個節點說明該節點是空閒的(H)還是已經使用§,以及內存的起始位置和長度。
      在這裏插入圖片描述
    • 例子,X代表要釋放的進程,陰影部分代表空閒
      在這裏插入圖片描述
      1. a中x釋放後,空閒鏈表P替換爲H,該空間空閒
      2. b和c的X釋放後,兩個相鄰的空閒區域合併成一個區域,鏈表變短
      3. d中X釋放後三個鏈表節點合併成一個
連續內存分配算法

截止目前我們討論的內存都是將內存作爲連續內存爲基礎的,連續內存指的是我們分配給進程的內存在空間上是連續的,在下一部分中會介紹虛擬內存,將會看到,進程是可以被分配不連續的內存。拿上邊圖中的空閒鏈表做例子
在這裏插入圖片描述

  • 首次適配算法(first fit)
    內存管理器沿着鏈表搜索,直到找到一塊足夠大的空閒內存,假設現在要分配的內存爲2,該算法將掃描鏈表,然後選擇編號2的空閒塊
  • 下次適配算法(next fit)
    和首次適配算法類似,只是搜索起始位置不同,首次適配算法是從頭開始,而下次適配算法是從上一次分配的位置開始
  • 最佳適配算法(best fit)
    最佳適配算法從頭開始搜索到結尾,找出最小的能容納進程的空閒塊,比首次適配算法慢。假設分配內存爲2,則掃描全表發現編號5的空閒塊最適合
  • 最差適配算法
    每次搜索最大的空閒內存塊,來減少內存碎片,掃描全表,發現編號2的空閒塊最大
  • 快速適配算法
    爲常用分配內存大小建立不同的項,分項存儲。和所有按空閒內存大小排序的算法一樣,當進程內存釋放或者換出時,查找相鄰塊判斷是否可以合併是非常耗時的。

總結

上述總結了通過無存儲器抽象到利用地址空間的抽象一步步解決從單進程到多進程問題、從進程需要小內存到內存無法容納進程的問題。雖然現代計算機有更高級的虛擬內存技術,學習一個技術很好的方式是瞭解其發展歷史,瞭解了歷史,對理解一個技術的誕生有很好的幫助,因爲可以知道爲什麼需要這個技術以及它解決的問題。在下一篇中將介紹虛擬內存技術。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章