資料結構45 動態記憶體管理機制

2022-07-07 19:00:15 字數 2265 閱讀 3708

通過前面的學習,介紹很多具體的資料結構的儲存以及遍歷的方式,過程中只是很表面地介紹了資料的儲存,而沒有涉及到更底層的有關的儲存空間的分配與**,從本節開始將做更深入地介紹。

在使用早期的計算機上編寫程式時,有關資料儲存在什麼位置等這樣的問題都是需要程式設計師自己來給資料分配記憶體。而現在的高階語言,大大的減少了程式設計師的工作,不需要直接和儲存空間打交道,程式在編譯時由編譯程式去合理地分配空間。

本章重點解決的問題是:

這裡的使用者,不是普通意義上的使用者,可能是乙個普通的變數,乙個應用程式,乙個命令等等。只要是向系統發出記憶體申請的,都可以稱之為使用者。

對於計算機中的記憶體來說,稱已經分配給使用者的的記憶體區統稱為「占用塊」;還未分配出去的記憶體區統稱為「空閒塊」或者「可利用空間塊」。對於初始狀態下的記憶體來說,整個空間都是乙個空閒塊(在編譯程式中稱為「堆」)。但是隨著不同的使用者不斷地提出儲存請求,系統依次分配。

整個記憶體區就會分割成兩個大部分:低位址區域會產生很多占用塊;高位址區域還是空閒塊。如圖 1 所示:

圖 1 動態分配過程中的記憶體狀態

但是當某些使用者執行結束,所占用的記憶體區域就變成了空閒塊,如圖 2 所示:

圖 2 動態分配過程中的記憶體變化

此時,就形成了占用塊和空閒塊犬牙交錯的狀態。當後續使用者請求分配記憶體時,系統有兩種分配方式:

系統繼續利用高位址區域的連續空閒塊分配給使用者,不去理會之前分配給使用者的記憶體區域的狀態。直到分配無法進行,也就是高位址的空閒塊不能滿足使用者的需求時,系統才會去**之前的空閒塊,重新組織繼續分配;

當使用者執行一結束,系統馬上將其所佔空間進行**。當有新的使用者請求分配記憶體時,系統遍歷所有的空閒塊,從中找出乙個合適的空閒塊分配給使用者。

合適的空閒塊指的是能夠滿足使用者要求的空閒塊,具體的查詢方式有多種,後續會介紹。

當採用第 2 種方式時,系統需要建立一張記錄所有空閒塊資訊的表。表的形式有兩種:目錄表和煉表。各自的結構如圖 3 所示:

圖 3 目錄表和煉表

空閒塊大小:記錄每個空閒塊的記憶體大小。

使用情況:記錄每個空閒塊是否儲存被占用的狀態。

鍊錶:表中每個結點代表乙個空閒塊,每個結點中需要記錄空閒塊的使用情況、大小和連線下乙個空閒塊的指標域。

由於鍊錶中有指標的存在,所以結點中不需要記錄各記憶體塊的起始位址。

系統在不同的環境中執行,根據使用者申請空間的不同,儲存空閒塊的可利用空間表有以下不同的結構:

如果每次使用者請求的儲存空間大小相同,對於此類系統中的記憶體來說,在使用者執行初期就將整個記憶體儲存塊按照所需大小進行分割,然後通過鍊錶鏈結。當使用者申請空間時,從鍊錶中摘除乙個結點歸其使用;用完後再鏈結到可利用空間表上。

每次如果使用者申請的都是若干種大小規格的儲存空間,針對這種情況可以建立若干個可利用空間表,每乙個鍊錶中的結點大小相同。當使用者申請某一規格大小的儲存空間時,就從對應的鍊錶中摘除乙個結點供其使用;用完後鏈結到相同規格大小的鍊錶中。

使用者申請的記憶體的大小不固定,所以造成系統分配的記憶體塊的大小也不確定,**時,鏈結到可利用空間表中每個結點的大小也各不一樣。

第 2 種情況下容易面臨的問題是:如果同使用者申請空間大小相同的鍊錶中沒有結點時,就需要找結點更大的鍊錶,從中取出乙個結點,一部分給使用者使用,剩餘部分插入到相應大小的鍊錶中;**時,將釋放的空閒塊插入到大小相同的鍊錶中去。如果沒有比使用者申請的記憶體空間相等甚至更大的結點時,就需要系統重新組織一些小的連續空間,然後給使用者使用。

通常情況下系統中的可利用空間表是第 3 種情況。如圖 3(c) 所示。由於鍊錶中各結點的大小不一,在使用者申請記憶體空間時,就需要從可利用空間表中找出乙個合適的結點,有三種查詢的方法:

以上三種方法各有所長:

同時,三種方法中,最佳擬合法相比於其它兩種方式,無論是分配過程還是**過程,都需要遍歷鍊錶,所有最費時間。無論使用以上三種分配方式中的哪一種,最終記憶體空間都會成為乙個乙個特別小的記憶體空間,對於使用者申請的空間的需求,單獨拿出任何乙個結點都不能夠滿足。

但是並不是說整個記憶體空間就不夠使用者使用。在這種情況下,就需要系統在**的過程考慮將位址相鄰的空閒塊合併。

合併的具體方法會在後面章節詳細介紹。

C語言 資料結構 預備知識動態記憶體分配

動態記憶體分配 靜態記憶體分配陣列 int a 5 動態記憶體分配陣列 int len 5 int parr int malloc sizeof int len 1.分配了 4 5 20 個位元組的記憶體空間,返回了第乙個位元組的位址 2.第乙個位元組的位址無意義,所以強制轉成 int型別的位址 i...

RTOS動態分割槽記憶體管理機制的優化設計

引 言 在嵌入式領域中,嵌入式實時作業系統 rtos 正得到越來越廣泛的應用。採用嵌入式實時作業系統可以更合理 更有效地利用cpu的資源,簡化應用軟體的設計,縮短系統開發時間,更好地保證系統的實時性和可靠性。記憶體資源作為嵌入式系統中極為重要的資源之一,其管理機制歷來是嵌入式系統設計的重點和難點。記...

linux kernel記憶體管理資料結構

是乙個全域性變數,指向乙個struct page陣列,管理著系統中的所有物理頁面,陣列中的每個page結構,對應乙個物理頁框.mem map僅當系統為單node時有效,對於arm平台,只有乙個node with no discontig,the global mem map is just set ...