linux缺頁
『壹』 linux內存,PageFault與SwapOut
「內存並不一定總是快」
Linux 中內存主要有匿名內存和 Page Cache 兩種。
Linux操作系統內存管理策略是會盡可能的利用內存來做各種緩存,所以一般來說伺服器所謂的free內存都會較少,當應用alloc申請內存的時候,如果free內存不足就會引發內存回收,這就是所謂的PageFault缺頁,這時候系統會先使用非同步方式的後台回收來提高應用申請內存這個操作的響應速度。但是如果應用申請內存的速度大於系統後台回收的速度的話,就會進入所謂直接回收(Direct Reclaim)模式,這是一個同步的過程,應用會大搭友自旋等待內存回收完畢,產生比較大的延遲。見下圖:
另一方面,內核會回收匿名內存頁,並將其置換到磁碟里(這是Linux所謂虛擬內存的管理方式,磁碟上的這部分用來跟內存做交換的空間稱為swap空間),匿名內存頁一旦被換出然後再次被訪問的時候,就會產生文件IO了(要從swap空間里把頁載入回內存里),這也會導致滾槐比較大的延遲。見下圖:
vm.extra_free_kbytes 和 vm.swappiness 兩個內核參數可以針對PageFault和SwapOut兩種內存訪問延遲做調優。mlock 系統調用可以讓應用程序「鎖定」一塊內存空間而不被內核swap出去。
萬億級數據洪峰下的分布式消息引擎-InfoQ
後記:
這篇小文來自於學習RocketMQ開發團隊的技術分享文章(見參考),里邊的「內存沒那麼快」觀點筆者認為更確切說法應該是「內存並不總是那麼快」,里邊的Linux內存管理的一小段說明加深了筆者對之前了解的概念的理解,這些東西可能平時工作未必有什麼用,但了解底層的東西總是會讓人產生求知求所得的愉悅感受。看了阿里褚霸的個人背景簡介,「14年c開發經枝攔驗, 12年網路開發經驗, 3年Linux內核開發」,他也遇到過「底層 IO(Input/Output) 技術。IO 技術涉及面非常廣,驅動,塊設備,文件系統,內存關系等等」 ,做專家終歸是要走入底層,到最後考驗的是對系統、對計算機的理解。本文很水,而腳下這條路不知能走多遠,但是想想不為什麼就算只為求知的喜悅我也是願意走下去的啊。這也是我為什麼要建「系統底層」這個專題
『貳』 Linux內核虛擬內存管理之匿名映射缺頁異常分析
讓我們深入探討Linux內核中的匿名映射缺頁異常,這個現象在內存管理中至關重要。本文基於linux-5.0內核源代碼進行講解,內容分為幾個部分。
首先,理解什麼是匿名頁至關重要。匿名頁與文件頁相對,它們不對應任何文件,比如進程的堆和棧。當程序使用malloc或mmap分配內存時,即使虛擬內存已分配,物理內存可能尚未分配,首次訪問時會觸發缺頁異常來為虛擬內存分配物理空間。
接著,我們聚焦於0頁的概念。在系統初始化時,會預先分配一頁全為0的內存,稱為0頁。0頁的使用在於節省內存,匿名頁第一次讀取時,如果數據是0,會映射到0頁,寫操作時則會觸發頁面復制。
當匿名映射缺頁異常發生時,處理器會觸發一系列處理流程。在源代碼中,handle_pte_fault函數會檢查頁表項是否缺失和是否為匿名映射,然後調用do_anonymous_page處理。這個函數會根據操作(讀寫)判斷是否使用0頁,並根據許可權設置頁表屬性。
在第一次讀寫匿名頁時,內核代碼會進行詳細處理,例如在mmap映射內存時,會檢查並設置頁的可讀寫屬性。如果是寫操作,即使之前設置了寫許可權,頁表項在第一次寫入時也會變為只讀,直到下次寫操作時才會分配新物理頁。
最後,通過實驗驗證了內核按需分配頁的策略,映射和寫操作前後內存使用情況的變化證實了匿名頁的動態分配特性。總結來說,匿名映射缺頁異常是內存管理中的關鍵點,理解它能幫助我們更好地優化程序性能和內存利用。