前言
寫的還很亂,沒把全部知識點串起來,以後再來吧,另外感覺沒圖讀起來確實不通順..學習自用,有錯麻煩提一下
進程空間的分配
進程空間的分配要與內核空間的分配區別開;一個進程會有相應的地址空間,這裏說的進程要與磁盤上的程序(可執行文件)給區分開來,首先講一下進程的空間結構:
進程的空間結構
編程語言裏常說的內存五區
-
全局區
-
靜態區
-
代碼區
-
堆棧
而實際中進程的分爲以下幾段(放圖TODO)
-
data section,用來存可執行文件的已初始化全局變量,如函數之外的int count=5;
-
BSS(未初始化變量),與data section相對,存的是未初始化的全局變量,如全局的int array[10]
-
text section的映射,即代碼段,,機器指令,可被共享,只讀
-
stack,用戶棧,要區分開內核棧
-
共享庫(shared lib),給共享庫的額外的text,data和bss,如C的庫
-
memory mapped files(是mmap調用生成的?)
-
共享內存區域,如什麼呢(有些定義不把這個單獨分開)
-
堆,有些管這個叫匿名映射區,如malloc分配的區域
對於這些區域空間,OS是怎麼管理的呢
進程空間的管理
在進程管理中,一個進程會產生一個task_struct用來存儲進程相關信息,而與現在關心的進程地址空間相關的數據結構是task_struct的mm成員
mm field存取此進程能合法尋址的區域的相關信息,即process address space的相關信息,這個區域用memory descriptor結構來表示,名爲mm_struct結構對應(這個數據結構也是由slab layer分配的),這個結構體裏包含:
-
memory area的鏈表和紅黑樹
-
堆棧,代碼區,數據區的起始位置
-
spinlock等
memory area則用vm_area_struct表示,在linux內核中又叫virtual memory area(VMA),用來描述一段連續的空間,包含:
-
vm_start and vm_end下一個節點
-
可執行的操作
進程是通過內核來對process address space進行添加刪除memory area的
在linux中,一個進程開始運行的時候,雖然有很大的address sapce(可尋址的空間),但是實際可以不佔任何物理頁,這個策略名爲demand page.等到進程去訪問某個頁的時候,纔會引發缺頁exception,再去分配物理空間;我們調用malloc或者brk實際就是這麼個情況.
brk()
略TODO
mmap()
略TODO
進程的創建fork
fork會拷貝哪些東西?TODO
寫時複製
因爲fork會複製所有空間給子進程,爲了防止fork以後再exec清空,於是用copy on write,作用是不會全部複製給子進程,而是共享這些片段,如代碼區,數據區,堆棧都是共享的,而當要修改的時候再分配單獨的物理空間,即寫的時候再複製
而vfork是,子進程直接寫在父進程的地址空間裏
地址空間
地址空間的轉換是通過mm_struct轉三級頁表再到struct page,從而找到物理頁的
分配空間
32位的系統的尋址空間是2的32次方,也就是4G空間,其中1G會被分配給內核,3G分給用戶空間;內核空間實際上只有839MB,其中100多MB預留給硬件,而這麼小的空間,不能直接尋址全部區域,超過尋址部分的就叫high memory,會通過其他手段映射,可以直接尋址的就叫low memory,