Linux記憶體布局

2021-10-06 20:53:43 字數 2184 閱讀 1682

我們先來看下linux記憶體布局,此圖比我之前寫的那篇文章寫的布局更詳細

在linux中,每乙個程序都被抽象為task_struct結構體,稱為程序描述符,儲存著程序

各方面的資訊;例如開啟的檔案,訊號以及記憶體等等;然後task_struct的乙個屬性mm_struct管理著程序的所有虛擬記憶體,稱為記憶體描述符。在mm_struct結構體中,儲存著程序各個記憶體段的開始以及結尾,如上圖所示;這個程序使用的物理記憶體,即常駐記憶體rss頁數,這個記憶體使用的虛擬位址空間vsz頁數,還有這個程序虛擬記憶體區域集合和頁表。

從上面這個圖可以看出,程序是有**段text segment,資料段(已初始化的全域性,靜態變數),bss段(未初始化的全域性,靜態變數),堆,記憶體對映區以及棧;

每一塊虛擬記憶體區(vma)都是由一塊連續的虛擬位址組成,這些位址從不覆蓋。乙個vm_area_struct例項描述了一塊記憶體區域,包括這塊記憶體區域的開始以及結尾位址;flags標誌決定了這塊記憶體的訪問許可權和行為;vm_file決定這塊記憶體是由哪個檔案對映的,如果沒有檔案對映,則這塊記憶體為匿名的(anonymous)。上述圖中提到的每個記憶體段,都對應於乙個vm_area_struct結構。如下圖所示

上圖即為/bin/gonzo程序的記憶體布局。程式的二進位制檔案對映到**段和資料段,**段為唯讀只執行,不可更改;全域性以及靜態的未初始化的變數對映到bss段,為匿名對映,堆和棧也是匿名對映,因為沒有相應的檔案對映;記憶體對映區可以對映共享庫,對映檔案以及匿名對映,所以這塊記憶體段可以是檔案對映也可以是匿名對映。而且不同的檔案,對映到不同的vm_area_struct區。

這些vm_area_struct集合儲存在mm_struct中的乙個單向鍊錶和紅黑樹中;當輸出/proc/pid/maps檔案時,只需要遍歷這個鍊錶即可。紅黑樹主要是為了快速定位到某乙個記憶體塊,紅黑樹的根儲存在mm_rb域。

之前介紹過,線性位址需要通過頁表才能轉換為實體地址。每個程序的記憶體描述符也儲存了這個程序頁表指標pgd,每一塊虛擬記憶體頁都和頁表的某一項對應。

虛擬記憶體是不儲存任何資料的,它只是將位址空間對映到物理記憶體。物理記憶體有核心夥伴系統分配,如果一塊物理記憶體沒有被對映,就可以被夥伴系統分配給虛擬記憶體。剛分配的物理記憶體葉框可能是匿名的,儲存程序資料,也可能是也快取,儲存檔案或塊裝置的資料。一塊虛擬記憶體vm_area_struct塊是由連續的虛擬記憶體頁組成的,而這些虛擬記憶體塊對映的物理記憶體卻不一定連續,如下圖所示:

如上圖所示,有三個頁對映到物理記憶體,還有兩個頁沒有對映,所以常駐記憶體rss為12kb,而虛擬記憶體大小為20kb。對於有對映到物理記憶體的三個頁的頁表項pte的present標誌設為1,而兩個沒有對映物理記憶體的虛擬記憶體頁表項的present位清除。所以這時訪問那兩塊記憶體,則會導致異常缺頁。

vma就像應用程式和核心的乙個契約。當應用程式申請記憶體或者檔案對映時,核心先響應這個請求,分配或更新虛擬記憶體;但是這些虛擬記憶體並沒有對映到真實的物理記憶體。而是等到記憶體訪問產生乙個記憶體異常缺頁時才真正對映物理記憶體。即當訪問沒有對映的虛擬記憶體時,由於頁表項的present位沒有被設定,所以此時會產生乙個缺頁異常。vma記錄和頁表項兩個在解決記憶體缺頁,釋放記憶體以及記憶體swap out都起著重要的作用。下面圖展示了上述情況:

1、一開始堆中只有8kb的記憶體,而且都已經對映到物理記憶體;

2、當呼叫brk()函式擴充套件堆時,新的頁是沒有對映到物理記憶體的,

3、當處理器需要訪問乙個位址,而且這個位址在上述剛分配的虛擬記憶體中,這時產生乙個缺頁異常;

4、這時程序向夥伴系統申請一頁的物理記憶體,對映到那塊虛擬記憶體上,並新增頁表項,設定present位.

自此,這個記憶體管理暫時就說到這。總結下:

1、linux程序的記憶體布局的每個段都是有乙個vm_area_struct,而這個例項是由連續的虛擬記憶體位址組成;

2、當請求記憶體時,先是擴充套件vm_area_struct或者新分配乙個vm_area_struct,但是並不對映物理記憶體,只有等到訪問這塊記憶體時,產生缺頁異常,核心才分配物理記憶體。

Linux記憶體布局

變數名稱 說明num physpages 最高可用頁框的頁框號 totalram pages 可用頁框的總數量 min low pfn ram 中在核心映像後第乙個可用頁框的頁框號 max pfn 最後乙個可用頁框的頁框號 max low pfn 被核心直接對映的最後乙個頁框的頁框號 低位址記憶體 ...

linux記憶體布局學習

linux系統中的程序總是以為自己是唯一的,那程序是如何被對映到記憶體中的呢?以前總是覺得這些東西太高深,可望而不可及 從現在開始,讓我們慢慢揭開這神秘的面紗。典型的linux c程式記憶體布局,從低位址到高位址分別如下 1.段,即cpu要執行的程式 段是可共享的,同乙份 在記憶體中只有乙份拷貝 段...

2Linux記憶體布局

變數名稱 說明 num physpages 最高可用頁框的頁框號 totalram pages 可用頁框的總數量 min low pfn ram 中在核心映像後第乙個可用頁框的頁框號 max pfn 最後乙個可用頁框的頁框號 max low pfn 被核心直接對映的最後乙個頁框的頁框號 低位址記憶體...