Linux內存管理(text、rodata、data、bss、stack&heap)
一、各內存區段的介紹
系統內的程序分為程序段和數據段,具體又可細分為一下幾個部分:
(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)