1. 程式人生 > >記憶體分配和外部碎片和內部碎片

記憶體分配和外部碎片和內部碎片

記憶體分配

其實最為簡單的記憶體分配的方法就是將記憶體分為多個固定大小的分割槽,每個分割槽只能容納一個程序,所以多道程式的程式數就會受到分割槽的限制,對於這種方法就是在一個分割槽空閒的時候就可以從輸入隊列當中選擇一個程序,以便調入到空閒分割槽,當程序終止時,其分割槽可以被其他程序所使用,這種方法最開始是被IBM OS/360作業系統使用,當然現在不再使用,因為其的規模龐大,執行緩慢,沒有什麼人使用

在可變分割槽方案裡,作業系統有一個表,用於記錄哪些記憶體可用和哪些記憶體和哪些記憶體已經被佔用,剛開始的時候,所有的記憶體都可用於使用者程序,因此我們可以把這塊記憶體看做是一個孔,當有新程序需要記憶體的時候,就去為該程序去查詢足夠大的孔,如果找到了,就可以從該孔為該程序分配所需的記憶體,孔內未分配的記憶體可以下次再去使用

在任意的時候都會有一組可用的孔大小列表和輸入佇列,作業系統根據排程演算法來對輸入佇列進行排序,記憶體不斷的分配給程序,直到下一個程序的記憶體不能滿足為止,這個時候沒有足夠大的可用的孔來裝入記憶體,作業系統就可以等到有足夠大的空間,或者往下掃描輸入佇列以確定是否有其他記憶體需求較小的程序可以被滿足

通常來說,一組大小不同的孔分散在記憶體當中,當新程序需要記憶體的時候,系統會為該程序查詢足夠大的孔,如果孔太大了,那麼就會分為兩塊,一塊分配給新程序,另一塊就還給孔集合,當程序終止時,它將釋放其的記憶體,這個記憶體就會還給孔集合,如果新孔與其他孔相鄰,那麼就會將這些孔給合併成大孔,這個時候,系統就可以去檢查是否有程序在等待記憶體空間,新合併的記憶體空間是否滿足等待程序

從一組可用的孔當中去選擇一個空閒的孔有很多種方法,一種就是首次適應,還有就是最佳適應,還有就是最差適應

  • 首次適應:分配第一個足夠大的孔,查詢從頭開始,也可以從上次首次適應結束時開始,一旦找到了足夠大的空閒孔,就可以停止
  • 最佳適應:分配最小的足夠大的孔,要去查詢整個列表,除非列表按照大小排序,這樣的話我們可以不用去遍歷整個列表,這種方法可以產生最小剩餘孔
  • 最差適應:分配最大的孔,同樣的也必須去查詢整個列表,除非列表按照大小排序,這種方法可以產生最大的剩餘孔,該孔可能比最佳適應方法產生的較小剩餘孔更為有用

其實首次適應和最佳適應方法在執行時間和利用空間方面都要好於最差適應方法,首次適應和最佳適應方法在利用空間方面差不多,不過首次適應方法會更快

外部碎片和內部碎片

外部碎片

隨著程序裝入和移出記憶體,空閒的記憶體空間被分為小片段,當所有的空閒的這些小片段的記憶體之和可以滿足請求,但是並不連續的時候,這個時候就會出現外部碎片的問題,這個問題可能會很嚴重,這個就是外部碎片

內部碎片

比如說我們有一個2018B大小的孔,並且採用了多分割槽的記憶體分配方案,假如有一個程序需要2016B,如果我們去準確的分配所需要的塊,那麼還剩下一個2B的孔,維護這個小孔的開銷要比孔本身大得多,因此,通常將記憶體以固定大小的塊為單位來分配,如果採用這種方案的話,程序所分配的記憶體可能要比所要的要大,這兩個數字之差就稱為內部碎片,這部分記憶體在分割槽當中,不過不能使用

解決外部碎片問題的方法

  • 1、緊縮法,緊縮的目的就是移動記憶體內容,以便所有空閒空間合併成一整塊,但是緊縮並不是所有的程式都是可以的,因為如果重定位是靜態的,也就是說在彙編時或裝入記憶體的時候進行的,那麼就不能緊縮,緊縮只是在重定位是動態並且在執行時可以採用,如果地址被動態重定位,就可以去移動程式和資料,然後去根據新基地址的值來改變基地址暫存器,如果我們採用了緊縮,我們還要去估計其的開銷,最簡單的合併演算法就是去將所有程序移動記憶體的一端,而將所有的孔移動到記憶體的另一端,這樣以生存一個大的空閒快,不過這種方案的開銷大
  • 2、還有一種就是可以是允許實體地址空間為非連續,這樣的話,我們只需要有實體地址就可以為程序去分配空間了

靜態重定位

靜態重定位就是在程式裝入記憶體的過程中完成,是指在程式開始執行前,程式中的各個地址有關的項均已完成重定位,地址變換通常是在裝入時一次完成的,以後不再改變

動態重定位

動態重定位:它不是在程式裝入記憶體時完成的,而是CPU每次訪問記憶體時 由動態地址變換機構(硬體)自動進行把相對地址轉換為絕對地址。動態重定位需要軟體和硬體相互配合完成。