Linux記憶體管理 14 匿名頁面生命週期

2021-09-12 06:35:16 字數 2714 閱讀 8425

專題:linux記憶體管理專題

如果要將匿名頁面的生命週期進行劃分,大概就是誕生、使用、換出、換入和銷毀。

核心中使用匿名頁面的地方有很多,產生缺頁中斷之後匿名頁面就誕生了;

使用者程序訪問虛擬位址即可訪問到匿名頁面內容;

在記憶體緊張的時候,需要**一些頁面來釋放記憶體,匿名頁面可能被換出;

如果虛擬位址空間被再次訪問,則需要將swap分割槽中內容換入

當程序關閉或者退出時,vma上的對映需要被清除,相關匿名頁面會被銷毀。

從核心的角度看,出現匿名頁面的情況有:

1. 使用者空間malloc/mmap介面函式來分配記憶體,在核心空間發生缺頁中斷時,呼叫do_anonymous_page()會產生匿名頁面。

2. 發生寫時複製,當缺頁中斷出現寫保護錯誤時,新分配的頁面是匿名頁面。

2.1 do_wp_page(),唯讀的special對映的頁面,例如對映到zeroed的頁面;非單身匿名頁面;唯讀的私有對映的page cache;ksm頁面。

3. do_swap_page(),從swap分割槽 讀回資料時會新分配匿名頁面。

4. 遷移頁面

匿名頁面在缺頁中斷中分配完成之後,就建立了程序虛擬位址空間vma和物理頁面的對映關係,使用者程序訪問虛擬位址即訪問到匿名頁面的內容。

假設系統記憶體緊張,需要**一些頁面來釋放記憶體。

anon_page剛分配時會加入活躍lru鍊錶(lru_active_anon)頭部,在經歷了活躍lru鍊錶的一段時間的移動,

該anon_page到達活躍lru鍊錶的尾部,shrink_active_list()函式把該頁加入不活躍lru鍊錶(lru_inactive_lru)。

shrink_inactive_list()函式掃瞄不活躍鍊錶,shrink_page_list()回首頁面。

(1) 第一次掃瞄不活躍鍊錶時,shrink_page_list()->add_to_swap()函式會為該頁分配swap分割槽空間

此時匿名頁面的_count、_mapcount、flags狀態如下:

page->_count = 3(引用計數增加的地方:1-分配頁面;2-分離頁面;3-add_to_swap())

page->_mapcount = 0

page->flags = pg_lru | pg_swapbacked pg_swapcache | pg_dirty | pg_uptedate | pg_locked,

pg_swapcache表示該頁已經分配了swap空間,pg_dirty表示該頁為臟,稍後需要寫回swap分割槽,pg_uptodate表示該也得資料是有效的。

(2) shrink_page_list()->try_to_unmap()後該匿名頁面狀態如下

page->_count = 2

page->_mapcount = -1---------表示沒有pte對映該頁

try_to_unmap()會通過rmap反響對映系統去尋找對映該頁的所有vma和相應的pte,並將這些pte解除對映。

因為該頁只和父程序建立了對映關係,因此_count和_mapcount都要減1。

(3) shrink_page_list()->pageout()函式把該頁寫回交換分割槽,此時匿名頁面狀態如下

page->_count = 2

page->_mapcount = -1

page->flags = pg_lru | pg_swapbacked | pg_swapcache | pg_dirty | pg_uptedate | pg_reclaim | pg_writeback

(4) 第二次掃瞄不活躍鍊錶

經歷第一次不活躍lru鍊錶的移動過程,從煉表頭移動到鍊錶尾。

如果這時該頁還沒有寫入完成,即pg_writeback標誌位還在,那麼該頁會繼續被放回到不活躍lru煉表頭,kswapd會繼續掃瞄其它頁,從而繼續等待寫完成。

假設第二次掃瞄不活躍鍊錶時,該頁寫入swap分割槽已經完成。block layer層毀掉函式end_swap_bio_write()->end_page_writeback()完成如下動作:

清pg_writeback標誌位

喚醒等待在該頁pg_writeback的執行緒,見wake_up_page(page, pg_writeback)函式。

page->_count = 0

page->_mapcount = -1

page->flags = pg_swapbacked | pg_uptedate

最後把page加入free_page鍊錶中,釋放該頁。因此該anon_page頁的狀態是頁面內容已經寫入swap分割槽,實際物理頁面已經釋放。

匿名頁面被換出到swap分割槽後,如果應用程式需要讀寫這個頁面,缺頁中斷發生。

因為pte中的l_pte_present位元位顯示該物理頁面不在記憶體中,但pte表項不為空,說明該頁被交換到swap分割槽去了,因此呼叫do_swap_page()函式重新讀入該頁的內容。

當使用者程序關閉或者退出時,會掃瞄這個使用者程序所有的vmas,並會清除這些vma上所有的對映,如果符合這些標準,相關頁面會被釋放。

uCOS III 14 記憶體管理

記憶體釋放函式 在嵌入式系統設計中,一些可靠性要求非常高的系統應選擇使用靜態的,而普通的業務系統可以使用動態來提高記憶體使用效率。ucos 的記憶體管理是建立乙個記憶體池,靜態劃分一大塊連續空間作為記憶體管理的空間,裡面劃分為很多個記憶體塊。在使用的時候就從這個記憶體池中獲取乙個記憶體塊,使用完畢的...

IOS 學習筆記14 記憶體管理(2)記憶體管理策略

文章中帶有lpstudy的字樣表明是我個人的理解,可能會有不對的地方,敬請指教。html view plain copy 記憶體管理策略 在引用計數機制下,你可以採用nsobject protocol的方法和和標準的方法命名約定進行記憶體管理。nsobject也定義了乙個dealloc方法,它在物件...

linux頁面管理

這裡很複雜,並且這裡為了程序的穩定之類的,並且包括程序資源的平均之類的東西,每種裝填的處理我也沒研究特別清楚,這裡僅僅記錄下一些思路,具體問題我不在過分解析,這裡先說下頁面管理的裝填,這裡僅僅寫出了四個佇列,可是還有乙個結構專門用來管理用於交換的page,這裡不在詳細說明,主要介篩下,關於空閒佇列,...