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