本文轉自:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201210975312473/
如何查看進程發生缺頁中斷的次數?
用ps -o majflt,minflt -C program命令查看。
majflt代表major fault,中文名叫大錯誤,minflt代表minor fault,中文名叫小錯誤。
這兩個數值表示一個進程自啟動以來所發生的缺頁中斷的次數。
發成缺頁中斷后,執行了那些操作?
當一個進程發生缺頁中斷的時候,進程會陷入內核態,執行以下操作:
1、檢查要訪問的虛擬地址是否合法
2、查找/分配一個物理頁
3、填充物理頁內容(讀取磁盤,或者直接置0,或者啥也不干)
4、建立映射關系(虛擬地址到物理地址)
重新執行發生缺頁中斷的那條指令
如果第3步,需要讀取磁盤,那么這次缺頁中斷就是majflt,否則就是minflt。
內存分配的原理
從操作系統角度來看,進程分配內存有兩種方式,分別由兩個系統調用完成:brk和mmap(不考慮共享內存)。
1、brk是將數據段(.data)的最高地址指針_edata往高地址推;
2、mmap是在進程的虛擬地址空間中(堆和棧中間,稱為文件映射區域的地方)找一塊空閑的虛擬內存。
這兩種方式分配的都是虛擬內存,沒有分配物理內存。在第一次訪問已分配的虛擬地址空間的時候,發生缺頁中斷,操作系統負責分配物理內存,然后建立虛擬內存和物理內存之間的映射關系。
在標准C庫中,提供了malloc/free函數分配釋放內存,這兩個函數底層是由brk,mmap,munmap這些系統調用實現的。
下面以一個例子來說明內存分配的原理:
情況一、malloc小於128k的內存,使用brk分配內存,將_edata往高地址推(只分配虛擬空間,不對應物理內存(因此沒有初始化),第一次讀/寫數據時,引起內核缺頁中斷,內核才分配對應的物理內存,然后虛擬地址空間建立映射關系),如下圖:

2、進程調用A=malloc(30K)以后,內存空間如圖2:
3、進程調用B=malloc(40K)以后,內存空間如圖3。
情況二、malloc大於128k的內存,使用mmap分配內存,在堆和棧之間找一塊空閑內存分配(對應獨立內存,而且初始化為0),如下圖:

5、進程調用D=malloc(100K)以后,內存空間如圖5;
6、進程調用free(C)以后,C對應的虛擬內存和物理內存一起釋放。

8、進程調用free(D)以后,如圖8所示: