介紹完內(nèi)存類別,內(nèi)存的基本結(jié)構(gòu),分段尋址原理,我們再來看我們程序是怎么使用內(nèi)存。
內(nèi)存中的程序
BSS段
通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域。BSS是英文Block Started by Symbol的簡稱。BSS段屬于靜態(tài)內(nèi)存分配?!敬鎯θ治闯跏蓟淖兞俊?/p>
數(shù)據(jù)段
數(shù)據(jù)段通常是指用來存放程序中 已初始化 的 全局變量 的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。 【存儲全局已初始化的變量】
代碼段
代碼段通常是指用來存放 程序執(zhí)行代碼 的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于 只讀 , 某些架構(gòu)也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些 只讀的常數(shù)變量 ,例如字符串常量等。程序段為程序代碼在內(nèi)存中的映射.一個程序可以在內(nèi)存中多有個副本.【存儲的是二進制后的程序代碼】
堆
堆是用于存放進程運行中被動態(tài)分配的內(nèi)存段,它的大小并不固定,可動態(tài)擴張或縮減。當進程調(diào)用malloc/free等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張)/釋放的內(nèi)存從堆中被剔除(堆被縮減)【存儲初始化的局部變量】
棧
棧又稱堆棧, 存放程序的 局部變量 (但不包括static聲明的變量, static 意味著 在數(shù)據(jù)段中 存放變量)。除此以外,在函數(shù)被調(diào)用時,棧用來傳遞參數(shù)和返回值。由于棧的先進先出特點,所以棧特別方便用來保存/恢復調(diào)用現(xiàn)場。儲動態(tài)內(nèi)存分配,需要程序員手工分配,手工釋放【儲存的動態(tài)未初始化變量】
cat /proc/maps 進程內(nèi)存映射
將C語言文件編譯成a.out文件,并執(zhí)行該文件#./a.out,查看執(zhí)行該文件對應的進程#ps au,可以看到2200就2200就是我們需要的pidut文件,并執(zhí)行該文件#./a.out查看執(zhí)行該文件對應的進程#ps au,可以看到2200就2200就是我們需要的pid,#cat /proc/2200/maps 。
#a.out #include
進程使用內(nèi)存狀況
參數(shù)解釋
#cat /proc/2200/maps
address: 0085d000-00872000 虛擬內(nèi)存區(qū)域的起始和終止地址文件所占的地址空間
perms:rw-p 權(quán)限:r=read, w=write, x=execute, s=shared, p=private(copy on write)
offset: 00000000 虛擬內(nèi)存區(qū)域在被映射文件中的偏移量
dev: 03:08 文件的主設備號和次設備號
inode: 設備的節(jié)點號,0表示沒有節(jié)點與內(nèi)存相對應
name: /lib/ld-2.2.12.so 被映射文件的文件名
#cat /proc/2200/statm
size:任務虛擬地址空間大小
ident:正在使用的物理內(nèi)存大小
Shared:共享頁數(shù)
Trs:程序所擁有的可執(zhí)行虛擬內(nèi)存大小
Lrs:被映像倒任務的虛擬內(nèi)存空間的庫的大小
Drs:程序數(shù)據(jù)段和用戶態(tài)的棧的大小
dt:臟頁數(shù)量
UNIX/LINUX系統(tǒng)進程情況
c語言在UNIX/LINUX系統(tǒng)內(nèi)存使用圖示
左邊的是UNIX/LINUX系統(tǒng)的執(zhí)行文件,右邊是對應進程邏輯地址空間的劃分情況。
堆棧區(qū)(stack),堆棧是由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。棧的申請是由系統(tǒng)自動分配,如在函數(shù)內(nèi)部申請一個局部變量 int h,同時判別所申請空間是否小于棧的剩余空間,如若小于的話,在堆棧中為其開辟空間,為程序提供內(nèi)存,否則將報異常提示棧溢出。
堆(heap),堆一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表。堆的申請是由程序員自己來操作的,在C中使用malloc函數(shù),而C++中使用new運算符,但是堆的申請過程比較復雜:當系統(tǒng)收到程序的申請時,會遍歷記錄空閑內(nèi)存地址的鏈表,以求尋找第一個空間大于所申請空間的堆結(jié)點,然后將該結(jié)點從空閑結(jié)點鏈表中刪除,并將該結(jié)點的空間分配給程序,此處應該注意的是有些情況下,新申請的內(nèi)存塊的首地址記錄本次分配的內(nèi)存塊大小,這樣在delete尤其是delete[]時就能正確的釋放內(nèi)存空間。
全局數(shù)據(jù)區(qū)(靜態(tài)區(qū)) (static),全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 另外文字常量區(qū),常量字符串就是放在這里,程序結(jié)束后有系統(tǒng)釋放。
程序代碼區(qū),放著函數(shù)體的二進制代碼。
-
Linux
+關(guān)注
關(guān)注
87文章
11310瀏覽量
209615 -
計算機
+關(guān)注
關(guān)注
19文章
7500瀏覽量
88031 -
內(nèi)存
+關(guān)注
關(guān)注
8文章
3028瀏覽量
74079
發(fā)布評論請先 登錄
相關(guān)推薦
評論