1. 程式人生 > >Linux內存管理(text、rodata、data、bss、stack&heap)

Linux內存管理(text、rodata、data、bss、stack&heap)

而是 tac load 部分 沒有 堆和棧 時也 先進先出 可能

一、各內存區段的介紹

系統內的程序分為程序段和數據段,具體又可細分為一下幾個部分:

(1)text段-代碼段

text段存放程序代碼,運行前就已經確定(編譯時確定),通常為只讀,可以直接在ROM或Flash中執行,無需加載到RAM。

在嵌入式開發中,有時為了特別的需求(例如加速),也可將某個模塊搬移到RAM中執行。

(2)rodata段(read-only-data)-常量區

rodata段存儲常量數據,比如程序中定義為const的全局變量,#define定義的常量,以及諸如“Hello World”的字符串常量。只讀數據,存儲在ROM中。

註意:有些立即數與指令編譯在一起,放在text段。

const修飾的全局變量在常量區;const修飾的局部變量只是為了防止修改,沒有放入常量區。

編譯器會去掉重復的字符串常量,程序的每個字符串常量只有一份。

有些系統中rodata段是多個進程共享的,目的是為了提高空間利用率。

(3)data段

data存儲已經初始化的全局變量,屬於靜態內存分配。(註意:初始化為0的全局變量還是被保存在BSS段)

static聲明的變量也存儲在數據段。

鏈接時初值加入執行文件;執行時,因為這些變量的值是可以被改變的,所以執行時期必須將其從ROM或Flash搬移到RAM。總之,data段會被加入ROM,但卻要尋址到RAM的地址。

(4)bss段

bss段存儲沒有初值的全局變量或默認為0的全局變量,屬於靜態內存分配。

bss段不占據執行文件空間(無需加入程序之中,只要鏈接時將其尋址到RAM即可),但占據程序運行時的內存空間。

執行期間必須將bss段內容全部設為0。

(5)stack段-棧

stack段存儲參數變量和局部變量,由系統進行申請和釋放,屬於靜態內存分配。

stack的特點是先進先出,可用於保存/恢復調用現場。

(6)heap-堆

heap段是程序運行過程中被動態分配的內存段,由用戶申請和釋放(例如malloc和free)。

申請時至少分配虛存,當真正存儲數據時才分配物理內存;釋放時也不是立即釋放物理內存,而是可能被重復利用。

二、總結

1、執行文件中包含了text、rodata、data段的內容,不包含bss段內容(一堆0放入執行文件沒有意義)。

2、程序被存儲的地址和執行時期的地址不一定一致。

LMA(load memory address):某程序區被存儲的地址

VMA(virtual memory address):程序區段在執行時期的地址

例如data段會被存儲在ROM,但執行時必須加載到RAM,則在ROM中的地址就稱為LMA,在RAM中的地址就是VMA。

3、堆和棧的內存增長方向是相反的:棧是從高地址向低地址生長,堆是從低地址向高地址生長。

4、局部變量存儲在stack中,編寫函數時要註意如果該函數被遞歸調用很多次,可能會引起stack overflow的問題。

(尤其在嵌入式開發中,內存資源有限,所有內存幾乎都會被填滿,stack overflow和stack unserflow都極可能引起很大問題)

Linux內存管理(text、rodata、data、bss、stack&heap)