linux進程空間的內存管理

前言

寫的還很亂,沒把全部知識點串起來,以後再來吧,另外感覺沒圖讀起來確實不通順..學習自用,有錯麻煩提一下

進程空間的分配

進程空間的分配要與內核空間的分配區別開;一個進程會有相應的地址空間,這裏說的進程要與磁盤上的程序(可執行文件)給區分開來,首先講一下進程的空間結構:

進程的空間結構

編程語言裏常說的內存五區

  • 全局區

  • 靜態區

  • 代碼區

  • 堆棧

而實際中進程的分爲以下幾段(放圖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,

 

參考資料

  1. 博客園

  2. CSDN

  3. understanding linux kernel

  4. linux development

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章