一個程序的內(nèi)存空間分布

一個程序的內(nèi)存空間:

  • 代碼段: 只讀,可共享; 代碼段(code segment/text segment )通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀, 某些架構(gòu)也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等。

  • 數(shù)據(jù)段: 儲存已被初始化了的靜態(tài)數(shù)據(jù)。數(shù)據(jù)段(data segment )通常是指用來存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。

  • BSS 段:未初始化的數(shù)據(jù)段. BSS 段(bss segment )通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域。BSS 是英文Block Started by Symbol 的簡稱。BSS 段屬于靜態(tài)內(nèi)存分配。

[ 注意:BSS段 和 data段的區(qū)別是 ,如果一個全局變量沒有被初始化(或被初始化為0),那么他就存放在bss段;如果一個全局變量被初始化為非0,那么他就被存放在data段。]

  • 堆(heap ): 堆是用于存放進(jìn)程運行中被動態(tài)分配的內(nèi)存段,它的大小并不固定,可動態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc 等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free 等函數(shù)釋放內(nèi)存時,被釋放的內(nèi)存從堆中被剔除(堆被縮減)

  • 棧(stack) :棧又稱堆棧,是用戶存放程序臨時創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“{} ”中定義的變量(但不包括static 聲明的變量,static 意味著在數(shù)據(jù)段中存放變量)。除此以外,在函數(shù)被調(diào)用時,其參數(shù)也會被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會被存放回棧中。由于棧的先進(jìn)先出特點,所以棧特別方便用來保存/ 恢復(fù)調(diào)用現(xiàn)場。從這個意義上講,我們可以把堆??闯梢粋€寄存、交換臨時數(shù)據(jù)的內(nèi)存區(qū)。

分布如下圖所示:


注意:
圖中間在棧和堆之間,有一個共享內(nèi)存的映射的區(qū)域。這個就是共享內(nèi)存存放的地方。一般共享內(nèi)存的默認(rèn)大小是32M。

image.png

一個查看程序 data段,bss段,代碼段的命令 : size命令

對于如下的兩個程序 :


p1.c
p2.c

區(qū)別在于 arr[10] 一個有初始化,一個沒有初始化。使用size命令查看一下:


text data bss 分別表示的是 代碼段,data段,bss段的大小

小結(jié) :
1、經(jīng)過初始化的全局變量和靜態(tài)變量保存在數(shù)據(jù)段中。
2、未經(jīng)初始化的全局變量和靜態(tài)變量保存在BSS段。
3、函數(shù)內(nèi)部聲明的局部變量保存在堆棧段中。
4、const修飾的全局變量保存在文本段中,const修飾的局部變量保存在堆棧段中。
5、字符串常量保存在文本段中。

read more:
http://blog.sina.com.cn/s/blog_53fab15a01019lbq.html


另外一個問題

上面說到了一個進(jìn)程的進(jìn)程空間分布,下面的寫一個進(jìn)程下多個線程的空間分布。

一個進(jìn)程下的多個線程的資源是共享的,只有 棧,棧指針和寄存器 是獨立的。這樣可以保證多個線程去訪問函數(shù)的時候,不會出現(xiàn)數(shù)據(jù)不一致的問題。

  • 每個線程獨立的棧有多大?
    默認(rèn)的線程棧是8m。

  • 如何修改默認(rèn)的線程棧的大?。?/p>

typedef struct __pthread_attr_s 
{ 
  int __detachstate; //分離狀態(tài) 
  int __schedpolicy;//調(diào)度策略 
  struct __sched_param __schedparam; 
  int __inheritsched; 
  int __scope;//線程優(yōu)先級的有效范圍 
  size_t __guardsize;// 
  int __stackaddr_set; 
  void *__stackaddr;//起始地址 
  size_t __stacksize;//表示堆棧的大小
}pthread_attr_t; 


// pthread_attr_t 線程的屬性
// 也就是我們創(chuàng)建線程的第二個參數(shù)
if(pthread_create(&p1,NULL,th1,NULL)!=0){
        cout<<"thread create error"<<endl;
}

可以配合pthread_attr_setstack使用設(shè)置線程棧,由此看來線程棧在所進(jìn)程的堆區(qū),所以線程與其所屬的進(jìn)程共享進(jìn)程的虛擬地址空間.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容