當前位置:
首頁 > 知識 > Linux內存管理

Linux內存管理


來自:羅道文的私房菜


鏈接:http://luodw.cc/2016/02/17/linux-memory/




今天這篇文章主要是我之前看Linux內核相關知識和博客

Gustavo Duarte

中。我主要是看了這篇博客,並且結合之前的知識,對內存管理的的理解又上升了一個檔次。所以想通過這篇文章總結下。



我們先來看下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,但是並不映射物理內存,只有等到訪問這塊內存時,產生缺頁異常,內核才分配物理內存。




●編號517,輸入編號直達本文



●輸入m獲取文章

目錄

推薦↓↓↓



大數據與人工智慧


更多推薦

18個技術類公眾微信


涵蓋:程序人生、演算法與數據結構、黑客技術與網路安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Linux學習 的精彩文章:

Docker 從入門到實踐
終於!期待已久的 Ubuntu 18.04 LTS 正式發布

TAG:Linux學習 |