malloc 底層實現及Linux記憶體分配原理

2021-10-08 18:28:30 字數 1755 閱讀 5530

1) malloc 函式實在虛擬位址空間中劃分一片區域,而沒有與物理頁對應。

1)當開闢的空間小於 128k 時,malloc 的底層實現是呼叫brk()系統呼叫函式來在虛擬位址空間分配記憶體,其主要移動指標_enddata(此時的 _enddata指的是 linux 位址空間中堆段的末尾位址,不是資料段的末尾位址,因為堆位址是向高位址增長的。)

2)當開闢的空間大於 128k 時,malloc 的底層實現是mmap()系統呼叫函式在虛擬位址空間中分配空間。這時候不再是單純的堆高_endata指標而是在堆和棧中間,稱為「檔案對映區域」的地方,找一塊空間來開闢。

上述只是完成了虛擬記憶體位址的分配(即,建立其虛擬記憶體和物理記憶體之間的對映關係),還沒有實際的分配記憶體(相當於只是宣告來占用虛擬記憶體位址,而沒有進行定義占用實際的物理頁,所以malloc申請的記憶體才沒有初始化)。

而當程序第一次對分配的記憶體進行訪問的時候,通過查詢頁表,發虛擬記憶體對應的頁沒有在物理記憶體中快取,則傳送缺頁中斷,這時候 os 核心 才負責分配並以頁位單位(4096)載入到物理記憶體(一般只載入缺頁,或更多頁)。。

當乙個程序發生缺頁中斷的時候,程序會陷入(trap)核心態,執行以下操作:

1)檢查要訪問的虛擬位址是否合法

2)根據虛擬記憶體中的對映頁表,在 swap 空間中尋找該頁。

3)如果沒有,則呼叫 nopage 函式,從磁碟中載入該頁到記憶體中(major fault:大錯誤)。如果有則直接使用(minor fault:小錯誤)。並填充(初始化)物理頁內容(讀取磁碟,或者直接置0,或者什麼都不做)

4)建立對映關係(虛擬位址到實體地址的對映關係)

5)重複執行發生缺頁中斷的那條指令

malloc 在申請空間時,所分配的儲存空間比所要求的要稍大一些,額外的空間用來記錄管理資訊——分配塊的長度,指向下乙個分配塊的指標等等。這就意味著如果寫過乙個已分配區的尾端,則會改寫後一塊的管理資訊(這是很危險的)。

另一方面,正是由於有記錄資訊,所以free()一塊記憶體時,是需要傳入頭節點指標,而不需要傳入具體大小就可以實現記憶體釋放了。

注意:使用brk()直接在堆中分配的記憶體,只有到高位址的記憶體釋放時,低位址的記憶體才能被釋放(因為只有乙個_edata指標)

乙個程序所能用的最大記憶體(堆區)為1g; 棧區1~2m

在 32 位 linux os 中,可以操縱 242 = 4g 大小的位址空間。而linux中,保留了高位的 1g 空間作為核心空間。

剩餘的 3g 定址空間是需要其他所有執行的程序進行分配的。

經過實驗,其最大分配的堆區是1g

測試**:

int

main()

cout << mb /

1024

<<

" g"

<< endl;

return0;

}// 輸出:

1 g

參考

malloc 底層實現及原理

linux記憶體分配原理

malloc底層實現

1.結論 2.背景 3.分配原理 4.具體情況 1 malloc 小於128k的記憶體時,使用brk系統呼叫在堆上申請記憶體 2 malloc 大於128k的記憶體時,使用mmap系統呼叫在棧與堆之間的對映區分配記憶體 1.結論 1 當開闢的空間小於 128k 時,呼叫 brk 函式,malloc ...

malloc底層實現

linux維護乙個break指標,這個指標指向堆空間某個位置。從堆起始位址到break之間的位址空間為對映好的,可以供程序訪問 而從break往上,是未對映的位址空間,如果訪問這段空間則程式會報錯。我們使用malloc進行記憶體分配就是從break往上進行的 而rlimit則是限制程序堆記憶體容量的...

malloc的底層實現

每個程序都有乙個虛擬記憶體空間,虛擬記憶體空間通過mmu 儲存器管理單元 對映到真正的物理空間,mmu是乙個硬體,利用儲存在主存中的查詢表翻譯虛擬位址,查詢表由作業系統管理,使用者無法獲取。虛擬位址空間給每個程序乙個假象,就像每個進城擁有4g的執行空間一樣,但是實際在使用記憶體的時候,虛擬位址空間通...