簡介: 本文主要介紹 Linux 2.6 中的頁面回收機制是如何工作的,反向映射是如何設計並實現的,以及 Linux 操作系統如何利用反向映射機制進行頁面地回收。 Linux 2.6 中關於反向映射和頁面回收的代碼在不斷地更新,不同版本的內核在這部分的代碼上會有很大差異,本文將基於 2.6.18.1 版本的內核來探討 Linux 中的反向映射和頁面回收。
為什麼要進行頁面回收
操作系統管理內存中的物理頁面,同時也擔任著內存分配的職責。應用程序可以通過內存分配函數向操作系統申請物理頁面;在使用完這些物理頁面之後,應用程序可以通過相應的內存釋放函數釋放這些物理頁面。但是,對於內存中的某些物理頁面來說,頁面的使用者並不會主動釋放它們,如果這些物理頁面一直被占用而得不到釋放,那麼無論計算機上可用的物理內存有多少,物理內存遲早都有被用完的時候。所以,對於無法被主動釋放的物理頁面來說,操作系統就需要提供相應的功能去釋放它們,Linux 中提供頁面回收算法這樣一種機制進行頁面回收。
一般來說,用於頁緩存的物理頁面無法被頁面的使用者主動釋放,因為它們不知道這些頁面何時應該被釋放。Linux 中頁緩存存在的最大好處就是可以讓程序從緩存中快速獲取數據,從而提升系統的性能。在系統負載不重的情況下,Linux 操作系統會分配較多的物理頁面用於頁緩存,從而提高程序的運行效率;但是在系統負載較重的情況下,Linux 操作系統就可能會適當回收用於緩存的頁面,並減少用於緩存的頁面的分配,從而滿足系統中優先級更高的內存分配請求。對於用戶進程來說,Linux 操作系統可以在它需要的時候為它分配物理內存,但是當用戶進程不再需要這些物理頁面的時候,如果用戶進程不主動釋放占用的頁面,Linux 操作系統也不會強制用戶進程去釋放這些物理頁面。基於上述這些情況,當內存中可用的物理頁面越來越少,並最終導致內存的使用捉襟見肘的時候,為了保證系統的順利運行,Linux 操作系統就會根據一定的算法去回收那些長期被占用並且沒有得到有效使用的物理頁面。
由操作系統內核本身使用的物理頁面不在 Linux 操作系統進行頁面回收的考慮范圍之內,這是因為與用戶進程相比,內核不需要占用非常多的內存,回收內核占用的物理頁面會顯著增加內核代碼的復雜性,潛在收益非常低。
如何進行頁面回收
哪些頁面可以被回收
內存中並非所有物理頁面都是可以進行回收的,總的來說,以下這些種物理頁面可以被 Linux 操作系統回收:
在頁面被操作系統回收之前,所有與之關聯的進程頁表項必須要斷開與該頁面之間的映射關系。對於匿名頁面來說,在頁面被回收之前,匿名頁面中的內容首先需要先被交換到交換區中去;如果要回收的頁面是“髒”頁面,那麼該頁面在被回收之前需要先將頁面中的數據寫回。
除此之外,其他的頁面要麼不可以被回收,要麼根本不必進行回收。比如,內核占用的頁面不會被回收;映射到內核空間中的頁面也不會被回收;內核在執行的過程中動態生成的頁面需要永駐內存;被鎖住的頁面不能被回收;而沒有被占用的物理頁面則根本不需要被回收。
進行頁面回收的時機
Linux 操作系統使用如下這兩種機制檢查系統內存的使用情況,從而確定可用的內存是否太少從而需要進行頁面回收。
如果操作系統在進行了內存回收操作之後仍然無法回收到足夠多的頁面以滿足上述內存要求,那麼操作系統只有最後一個選擇,那就是使用 OOM( out of memory )killer,它從系統中挑選一個最合適的進程殺死它,並釋放該進程所占用的所有頁面。
上面介紹的內存回收機制主要依賴於三個字段:pages_min,pages_low 以及 pages_high。每個內存區域( zone )都在其區域描述符中定義了這樣三個字段,這三個字段的具體含義如下表 1 所示。