1. 程式人生 > >資料段、程式碼段、堆疊段、BSS段的區別

資料段、程式碼段、堆疊段、BSS段的區別

       程序(執行的程式)會佔用一定數量的記憶體,它或是用來存放從磁碟載入的程式程式碼,或是存放取自使用者輸入的資料等等。不過程序對這些記憶體的管理方式因記憶體用途 不一而不盡相同,有些記憶體是事先靜態分配和統一回收的,而有些卻是按需要動態分配和回收的。對任何一個普通程序來講,它都會涉及到5種不同的資料段。

Linux程序的五個段

下面我們來簡單歸納一下程序對應的記憶體空間中所包含的5種不同的資料區都是幹什麼的。

BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全域性變數的一塊記憶體區域。BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體分配。

資料段:資料段(data segment)通常是指用來存放程式中已初始化的全域性變數的一塊記憶體區域。資料段屬於靜態記憶體分配。

程式碼段:程式碼段(code segment/text segment)通常是指用來存放程式執行程式碼的一塊記憶體區域。這部分割槽域的大小在程式執行前就已經確定,並且記憶體區域通常屬於只讀, 某些架構也允許程式碼段為可寫,即允許修改程式。在程式碼段中,也有可能包含一些只讀的常數變數,例如字串常量等。

堆(heap):堆是用於存放程序執行中被動態分配的記憶體段,它的大小並不固定,可動態擴張或縮減。當程序呼叫malloc等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用free等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

棧(stack):棧又稱堆疊, 是使用者存放程式臨時建立的區域性變數,也就是說我們函式括弧“{}”中定義的變數(但不包括static宣告的變數,static意味著在資料段中存放變數)。除此以外,在函式被呼叫時,其引數也會被壓入發起呼叫的程序棧中,並且待到呼叫結束後,函式的返回值也會被存放回棧中。由於棧的先進後出特點,所以棧特別方便用來儲存/恢復呼叫現場。從這個意義上講,我們可以把堆疊看成一個寄存、交換臨時資料的記憶體區。

它是由作業系統分配的,記憶體的申請與回收都由OS管理。

PS:

全域性的未初始化變數存在於.bss段中,具體體現為一個佔位符;全域性的已初始化變數存於.data段中;而函式內的自動變數都在棧上分配空間。.bss是不佔用.exe檔案空間的,其內容由作業系統初始化(清零);而.data卻需要佔用,其內容由程式初始化,因此造成了上述情況。

bss段(未手動初始化的資料)並不給該段的資料分配空間,只是記錄資料所需空間的大小。
data(已手動初始化的資料)段則為資料分配空間,資料儲存在目標檔案中。 資料段包含經過初始化的全域性變數以及它們的值。BSS段的大小從可執行檔案中得到 ,然後連結器得到這個大小的記憶體塊,緊跟在資料段後面。當這個記憶體區進入程式的地址空間後全部清零。包含資料段和BSS段的整個區段此時通常稱為資料區。