Linux 內存管理簡單入門

在進程的執行過程中,Linux 內核會根據需要給進程分配一塊內存區域,進程就把這塊區域作爲工作區,按需求執行操作。內核會以更加動態的方式分配空間。系統上運行的進程成千上萬,但內存是有限的。因此,Linux 必須高效地處理內存資源。

1. 物理內存和虛擬內存

物理內存就是系統硬件提供的內存大小,是真正的內存。在 Linux 下還有一個邏輯內存的概念,邏輯內存就是爲了滿足物理內存的不足而提出的策略,它是利用磁盤空間虛擬出的一塊邏輯內存區域,用作邏輯內存的磁盤空間被稱爲交換空間(Swap Space)。但是,在 LInux 操作系統中,無論是系統內核,還是應用程序都不能直接使用物理內存和邏輯內存,要使用這些內存,需要通過一個映射機制來實現。也就是說,Linux 操作系統會把所有內存(包括物理內存和虛擬內存)都映射成虛擬內存,這樣,應用程序在使用內存時,就需要向 Linux 內核申請一個特定大小的內存映射,並且收到一個虛擬內存的映射。這個申請到的虛擬內存不一定全部是物理內存的映射,還可能包含由磁盤上的交換空間映射來的內存。

Linux 的這種虛擬內存管理機制對用戶和應用程序通常時不可見的。所以,掌握內存調優的方法,就必須要理解內存架構、地址佈局以及 Linux 如何高效管理內存空間。

2. 頁高速緩存和頁寫回機制

頁是物理內存或虛擬內存中一組連續的線性地址,Linux 內核以頁爲單位處理內存,頁的大小通常是 4KB。當一個進程請求一定數量的頁時,如果有可用的頁,內核會直接把這些頁分配給進程,否則,內核會從其他進程或者頁緩存中拿來一部分給這個進程用。內核知道有多少頁可用,也知道它們的位置。

如果進程請求指定數量的內存頁時沒有可用的內存頁,內核會嘗試釋放特定的內存頁給新的請求使用。這個過程叫作內存回收。其中,kswapd 內核進程負責頁面回收。

kswapd 在虛擬內存管理頁中負責換頁,操作系統每過一段時間就會喚醒 kswapd,它基於最近很少使用原則(Least Recently Used,LRU)在活動頁中找可回收的頁面,看看內存是否緊張,如果不緊張,則進入睡眠狀態。在 kswapd 中有兩個閾值(pages_high 和 pages_low),當空閒內存頁數量低於 pages_low 的時候 kswap 進程就會掃描內存並且每次釋放出 32 個 free pages,直到 free pages 的數量達到 pages_high。

Linux 在負載比較大(內存緊張)的時候一般會看到這樣兩個進程:kswap0 和 kswap1。如果這些進程佔用資源非常高,就要考據優化系統或添加硬件資源。

在某些情況下,kswapd 進程如果被頻繁喚醒會過度消耗 CPU,此時可以通過設置大頁內存(HugePages)來解決。

需要注意的,頁面回收會丟棄緩存、丟棄 Swap,這一定程度上會影響系統性能,而 kswapd 進程要做的是維護系統性能與頁面分配的平衡。

3.Swap 內存空間

Swap  space 是磁盤上的一塊區域,可以是一個分區,也可以是一個文件,或者是他們的組合。Linux 的內存管理採取的是分頁存取機制,爲了保證物理內存能得到充分的利用,內核會在適當的時候將物理內存中不經常使用的內存頁面自動交換到 Swap 交換空間中,而將經常使用的信息保留到物理內存。簡單點說,當系統物理內存喫緊時,Linux 會將內存中不常訪問的數據保存到 Swap 上,這樣系統就有更多的物理內存爲各個進程服務,而當系統需要訪問 swap 上存儲的內容時,再將 swap 上的數據加載到內存中。

雖然大部分情況下,物理內存都是夠用的,但是總有一些意想不到的狀況,比如某個進程需要的內存超過了預期,或者有進程存在內存泄漏等,當內存不夠的時候,就會觸發內核的 OOM killer,某些進程會被 kill 掉或者系統直接重啓。不過有了 Swap 後,可以拿 swap 當內存用,雖然速度慢了點,但至少給了我們一個去 debug、kill 進程或者保存當前工作進度的機會。

OOM Killer 通過檢查所有正在運行的進程並給它們分配一個不良分數,得分最高的進程會被終止。評分規則如下:

  • 進程及其所有子進程都在使用大量內存。

  • 爲了釋放足夠的內存,需要終止(理想情況下是一個)最少數量的進程。

  • 根進程、內核進程和重要系統進程的得分要低得多。

首先,Linux 系統會不時地進行頁面交換操作,以保持儘可能多的空閒物理內存,即使沒有什麼事情需要內存,Linux 也會交換出暫時不用的內存頁面。

其次,交換是有條件的,不是所有頁面在不用時都交換到 Swap。Linux 內核根據 “最近最少使用的” 算法,僅僅將最近很少使用的頁面文件交換到 Swap。有時會看到一個現象:Linux 物理內存還有很多,但是 Swap 卻仍使用了很多。這時因爲一個佔用很大內存的進程在運行時,需要耗費很多內存資源,此時就會有一些不常用的頁面文件被交換到 Swap 中。但後來這個佔用很多內存資源的進程結束並釋放了很多物理內存時,剛纔被交換出去的頁面文件並不會自動地交換進物理內存進行釋放,除非有這個必要。那麼此時就會出現系統物理內存空閒很多,但交換空間仍在被大量使用的現象。

查看 / proc/sys/vm/swappiness,vm.swappiness=0 表示禁用交換區,vm.swappiness=100 表示盡最使用交換區。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/4khJoIr9y_uFXw5_JcvD2A