記憶體分布和記憶體管理

2021-10-11 04:30:02 字數 2939 閱讀 3934

一、程序虛擬記憶體分布

名稱儲存內容

棧區域性變數,函式引數,返回位址等

堆動態分配的記憶體

bss段

未初始化或初值為0的全域性變數和靜態區域性變數

資料段已初始化且初值非0的全域性變數和靜態區域性變數

**段可執行**,字串字面值,唯讀變數

核心空間 堆疊

持續地重用棧空間有助於使活躍的棧記憶體保持在cpu快取中,從而加速訪問。程序中的每個執行緒都有屬於自己的棧。向棧中不斷壓入資料時,若超出其容量就會耗盡棧對應的記憶體區域,從而觸發乙個頁錯誤。此時若棧的大小低於堆疊最大值rlimit_stack(通常是8m),則棧會動態增長,程式繼續執行。對映的棧區擴充套件到所需大小後,不再收縮。

linux中ulimit -s命令可檢視和設定堆疊最大值,當程式使用的堆疊超過該值時, 發生棧溢位(stack overflow),程式收到乙個段錯誤(segmentation fault)。注意,調高堆疊容量可能會增加記憶體開銷和啟動時間。

堆疊的大小在執行時由核心動態調整。

記憶體對映區

該區域用於對映可執行檔案用到的動態鏈結庫。在linux 2.4版本中,若可執行檔案依賴共享庫,則系統會為這些動態庫在從0x40000000開始的位址分配相應空間,並在程式裝載時將其載入到該空間。在linux 2.6核心中,共享庫的起始位址被往上移動至更靠近棧區的位置。

從程序位址空間的布局可以看到,在有共享庫的情況下,留給堆的可用空間還有兩處:一處是從.bss段到0x40000000,約不到1gb的空間;另一處是從共享庫到棧之間的空間,約不到2gb。這兩塊空間大小取決於棧、共享庫的大小和數量。在linux2.6版本之前,共享庫的裝載位址為0x40000000,在2.6版本裡,共享庫的裝載位址已經被挪到靠近棧的位置,即位於0xbf******附近,因此,此時的堆範圍就不會被共享庫分割成2個「碎片」,故kernel 2.6的32位linux系統中,malloc申請的最大記憶體理論值在2.9gb左右。堆

保留空間

二、堆記憶體管理機制 平台

堆記憶體分配機制

glibc

ptmalloc2

google

tcmalloc

solaris(unix衍生)

libumem

free bsd(類unix系統) and firefox

jemalloc

general purpose allocator(一般用途分配器)

dlmalloc

ptmalloc2

(1)fast bins:fast bins是small bins的高速緩衝區。fast bin使用單向鍊錶實現。當程式執行需要申請和釋放一些較小的記憶體空間。一般對於不大於max_fast(在size_sz為4b的平台預設是64b)的chunk釋放後就會先被放到fast bins中,fast bins中有七個chunk空閒鍊錶(bin),每個bin的chunk大小依次為16b、24b、32b、40b…64b。fast bins中的chunk並不改變它的使用標誌p,這樣就無法合併他們。當需要給使用者分配小於或者是等於max_fast大小的記憶體時,ptmalloc會首先在fast bins中查詢,然後才會去bins中查詢空閒的chunk。有時候ptmalloc也會遍歷fast bins中的chunk,將相鄰的空閒的chunk進行合併,並將合併後的chunk加入到unsorted bin中,然後將unsorted bin中的chunk加入到bin中。

​(2)unsorted bin:相當於small bins和large bins的乙個緩衝區,unsorted bin是bins陣列中的第乙個,用雙向鍊錶管理chunk,空閒的chunk不排序,所有的chunk在**時都要先放到unsorted bin中。進行malloc操作時,如果fast_bins中沒有找到合適的chunk,則ptmalloc就會在unsorted bin中查詢空閒的chunk,如果unsorted bin中沒有合適的chunk,就會把unsorted bin中所有chunk分別加入到所屬的bin中,然後再在bin中查詢合適的chunk。bins陣列中元素bin[1]用來儲存unsorted bin的煉表頭。

​(3)small bins:陣列中從2號下標開始的到64號下標的62個bin稱為small bins。同乙個small bin中的chunk具有相同的大小,兩個相鄰的small bin中的chunk大小在size_sz為4b的平台上相差 8bytes,在size_sz為8b的平台上相差 16bytes。small bin 中chunk按照最近使用順序進行排列,最後釋放的chunk被連線到鍊錶的頭部,而申請的chunk是從鍊錶尾部開始的。

(4)large bins:在size_sz為4b的平台上,大於等於512b的空閒的chunk由large bin管理。large bins一共包含63個bin,每個bin中的chunk大小不是乙個固定的等差數列,而是分成6組bin,每組bin是乙個固定的等差數列。每組bin數量依次為32、16、8、4、2、1,公差依次為64b、512b、4096b、32768b、262144b等。

​(5)top chunk:並不是所有的chunk都會被放到bins上。top chunk相當於分配區的頂部空閒記憶體,當bins上都不能滿足記憶體分配要求的時候,就會來top chunk上分配。

(6)mmaped chunk:當需要分配的chunk​足夠大,fast bins和bins都不能滿足要求,甚至top chunk都不能滿足分配需求時,ptmalloc會使用mmap來直接使用頁對映機制來將頁對映到程序空間。這樣分配的chunk在被free時將直接解除對映,於是就將記憶體歸還給作業系統,再次對這樣的記憶體區的引用將導致錯誤。

【參考文獻】

understanding glibc malloc

linux 堆記憶體管理深入分析

linux虛擬位址空間布局

ptmalloc2記憶體管理機制

glibc記憶體管理-ptmalloc2

c語言malloc函式詳解

記憶體管理之程式在記憶體中的分布

段 txt 也稱文字段 text segment 存放著程式的機器碼和唯讀資料,可執行指令就是從這裡取得的。如果可能,系統會安排好相同程式的多個執行實體共享這些例項 這個段在記憶體中一般被標記為唯讀,任何對該區的寫操作都會導致段錯誤 segmentation fault 已初始化的資料段 data ...

《記憶體管理》 記憶體

1.c c 記憶體分布 我們先來看下面的一段 和相關問題 int globalvar 1 static int staticglobalvar 1 void test char char2 abcd char pchar3 abcd int ptr1 int malloc sizeof int 4 ...

WinCE執行緒和記憶體管理之記憶體管理

三 記憶體管理 同其它windows作業系統一樣,windows ce.net也支援32位虛擬記憶體機制 按需分配記憶體和記憶體對映檔案等。但是與其它windows作業系統又有明顯的不同。畢竟windows ce是一種嵌入式實時性的作業系統,在記憶體管理方面必須要比其它windows作業系統更節約物...