Linux 進程的內存管理
內存是計算機的敏感資源,能夠熟練的掌握內存的操作是一個優秀的程序員必備的素質!
數據的內部存儲
在c語言中,不同的數據類型佔用的`空間是不同的,比如說一個char類型,佔用的是一個字節長度,一個int 類型,一般佔用的是4個字節(與系統有關)
對於多個字節的的數據存儲,數據存儲的順序就顯得比較重要的了,一般來說,是有兩種存儲方式,一個是大端存儲,另一個就是小端存儲
那麼什麼是大端存儲,什麼是小端存儲呢?現在舉例說明,
例如,一個整型數據爲a=0x12345678,如果是小端存儲,則我們設置一個指針指向這個數據時,這個指針指向的的是78,也就是說,如果一個 整型數我們用四個字節來存儲,我們的數的低位存儲在內存的低位,數的高位存儲在內存的高位,這就是低端存儲,如果想反,則就是高端存儲。根據這個解釋,我們可以寫下以下的代碼,來測試自己的機器到底是低端存儲還是高端存儲。
1 /* 2 * ===================================================================================== 3 * 4 * Filename: test3.c 5 * 6 * Description: 7 * 8 * Version: 1.0 9 * Created: 2012年05月19日 00時48分26秒 10 * Revision: none 11 * Compiler: gcc 12 * 13 * Author: YOUR NAME (), 14 * Organization: 15 * 16 * ===================================================================================== 17 */ 18 #include <stdio.h> 19 int main() 20 { 21 int a=0x12345678; 22 char *p; 23 p=(char *)(&a); 24 if(*p==0x78) 25 printf("the little endian\n"); 26 else 27 printf("the big endian\n"); 28 return 0; 29 }
然後,我們講述一下, 什麼是進程!一個程序被加載到內存中運行,那麼在內存中那個數據就被稱爲是一個進程!
程序: 通常爲二進制文件,放置在存儲媒質中,以物理形式存在!
進程:程序被觸發後,執行者的權限屬性,程序代碼以及需要的數據都會被加載到內存中,這個被稱爲進程!
在內存中,數據分爲爲如下段:
1代碼段
代碼段可以說是進程中最重要的一個段,該段是cpu執行的指令部分,通常這個段被稱爲代碼段 有的書上也把這個段稱爲文本段!。
通常來說,子進程與父進程是共享代碼段的!
2 數據段
這個部分存儲的是在程序中明確給定初始值的全局變量和靜態變量 例如:int max=10;(全局變量)or static int n=10;(靜態變量)這些變量在內存中的數據段中存儲,當程序在編譯的時候確定該段的大小,在程序運行時該段大小是不變的
3 bss 段
又稱緩衝段,這個部分存儲的是在程序中沒有給地定初始值的全局變量和靜態變量,在這個數據段中,你會發現在生成的鏈接文件是沒有包含這些全局變量
下面我們可以用一個程序來看出這個問題!
#include <stdio.h> int a[30]; int main() { printf("hello world\n"); return 0; }
在添加了int a[30]後,我們發現生成的目標文件的大小是7177,沒有添加後,我們發現文件的大小是7159,我們發現只是少了18個字節,而在二進制文件中,一個int a[20]這樣的數組是需要30×4=120個字節的大小,從這裏可以看出,這個數組並沒有在這個二進制的文件中,也就是說,它被存儲在另外的外存中!如果我們是將這個全局數組初始成全爲0,我們發現其文件大小仍然是7177,這個說明初始化後,這個數組是寫到了bss段,沒有寫到數據段!仍然這個數組並沒有寫進二進制文件中去!
4,棧
對於局部變量,還有一些函數調用所需要保存的信息(如返回的地址,函數調用前在各個寄存器中的變量)都可以保存到棧中!
總結一下,變量的存儲方式,對於初始化不爲0的全局變量,和靜態變量保存到數據段,沒有初始化,或初始化爲0的全局變量保存到bss段,還有一部分變量是保存到寄存器中,
剩餘絕大多數的變量是保存到棧中!
5,堆
堆用於存儲用戶申請的內存空間,系統通常在堆中進行動態的內存分配,
在c語言中進行動態內存分配的函數是malloc函數,例如: char *p=(char *)malloc(sizeof(char)) 則p就指向了申請的新內存塊中的首地址!
對於常量的存儲
對於簡單的常量,如 '1' 'b',等常量,是隨指令一起存儲,也就是說,它們在代碼段中,這樣能夠進行高效的運算,但對於複雜的常量,如字符串常量,則並不是,編譯器會將其值保存到數據段中,然後把其存儲的首地址隨着指令存儲!