1. 程式人生 > 實用技巧 >Linux記憶體管理

Linux記憶體管理

Linux記憶體管理

記憶體只有在程序使用的時候才有意義,我們可以這麼理解,記憶體其實是輔助程序的一個重要資源。為什麼這麼理解,是因為計算機最重要的資源是CPU,而作業系統管理使用CPU的基本單元就是程序,所以能夠幫助程序最大程度排程CPU資源的外在資源都是輔助資源(暫時找不到合適的表達)

既然可以這麼理解,那麼程序如何使用記憶體呢?

程序描述符PCB裡面包含了作業系統管理一個程序所需要的全部資訊,比如程序開啟的檔案,訊號以及記憶體等,然後PCB的一個屬性mm_struct管理著程序的虛擬記憶體,稱為記憶體描述符。在mm_struct中,儲存著程序所使用的全部記憶體資訊。

/*
18. 程序地址空間 
    1) mm: 指向程序所擁有的記憶體描述符 
    2) active_mm: active_mm指向程序執行時所使用的記憶體描述符
對於普通程序而言,這兩個指標變數的值相同。但是,核心執行緒不擁有任何記憶體描述符,所以它們的mm成員總是為NULL。當核心執行緒得以執行時,它的active_mm成員被初始化為前一個執行程序的active_mm值
*/
struct mm_struct *mm, *active_mm;

用圖表示更清楚些:

如圖示,程序的記憶體段包括:程式碼段(Text segment)、資料段(Data segment:儲存已經初始化的全域性變數和靜態成員變數)、BSS段(未初始化的全域性和靜態變數)、堆、記憶體對映區和棧

每個記憶體段都對應一個vm_area_struct來描述記憶體區域,其中包括這塊記憶體區域的起始和結束地址。flags標誌決定了這塊記憶體的訪問許可權和行為。vm_file決定這塊記憶體是由哪個檔案對映的,如果沒有那就是匿名對映。

圖示是/bin/gonzo程序的記憶體佈局。程式的二進位制檔案對映到程式碼段和資料段,程式碼段為只讀只執行,不可更改。全域性以及靜態的未初始化的變數對映到BSS段,為匿名對映,堆和棧都是匿名對映,因為沒有相應的檔案會對映到該部分。

記憶體對映區可以對映共享庫,對映檔案,或者匿名對映,所以這塊記憶體可以是檔案對映也可以是匿名對映,不同的檔案對映到不同的vm_area_struct區,所以是有多少個檔案對映,就會有多少個vm_area_struct。

虛擬記憶體不儲存任何資料,它只是將地址對映到實體記憶體。一個vm_area_struct塊是由連續的虛擬記憶體頁組成,但是這些虛擬記憶體頁對映的實體記憶體卻不一定是連續。

如圖示,有三個虛擬記憶體頁對映到實體記憶體,還有兩個沒有對映。所以常駐記憶體RSS為12kb,虛擬記憶體大小為20kb,對於有對映的三個虛擬記憶體頁,對映到的實體記憶體也不是連續的。

簡單總結一下:

1、每個程序的記憶體佈局都有一個vm_area_struct,而這個結構體是由連續的虛擬記憶體地址組成。

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

原文連結:http://luodw.cc/2016/02/17/linux-memory/