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都極可能引起很大問題)

 

嗯,暫時先記錄這些吧。后續會在評論里進行補充和糾正。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM