一、Swap 原理
前面提到,Swap 說白了就是把一塊磁盤空間或者一個本地文件(以下講解以磁盤為例),當成內存來使用。它包括換出和換入兩個過程
1、所謂換出
就是把進程暫時不用的內存數據存儲到磁盤中,並釋放這些數據占用的內存。
2、換入
則是在進程再次訪問這些內存的時候,把它們從磁盤讀到內存中來
所以你看,Swap 其實是把系統的可用內存變大了。這樣,即使服務器的內存不足,也可以運行大內存的應用程序
3、應用場景
即是內存不足時,有些程序也並不像被OOM殺死,二十希望能緩一段時間,等待人工介入,或者等系統自動釋放其他程序的內存,再分配給它(可以給運維人員處理故障一個緩沖的時間)
常見的筆記本電腦休眠和快速開機的功能,也基於Swap ,休眠時,把系統內存存入磁盤,這樣等到再次開機時,只要從磁盤中加載內存就可以,這樣就省去了很多應用程序的初始化過程,加快了開機速度
二、那么 Linux 到底在什么時候需要回收內存呢?
1、直接內存回收
有新的大塊內存分配請求,但是剩余內存不足,這個時候系統就需要回收一部分內存(比如前面提到的緩存),進而盡可能地滿足新內存請求,這個過程被稱為直接內存回收
2、kswapd0(定期回收內存)
1、剩余內存頁<最小閾值
root@openstack:~# free -h total used free shared buff/cache available Mem: 4.9G 114M 4.0G 992K 770M 4.5G Swap: 3.9G 0B 3.9G root@openstack:~# cat /proc/sys/vm/min_free_kbytes 67584
說明進程可用內存都耗盡了,只有內核才可以分配內存
2、頁最小閾值<剩余內存頁<頁低閾值
內存壓力比較大,剩余內存不多了,這是kswapd0會執行內存回收,直接剩余內存大於高閾值為止
3、頁低閾值<剩余內存<頁高閾值
說明有一定壓力,但還可以滿足新內存請求
4、剩余內存>頁高閾值
說明剩余內存比較多,沒有內存壓力
watch -d grep -A 15 'Normal' /proc/zoneinfo Every 2.0s: grep -A 15 Normal /proc/zoneinfo openstack: Wed Feb 6 08:45:01 2019 Node 0, zone Normal pages free 146583 min 4986 low 6232 high 7478 spanned 399872 present 399872 managed 373102 protection: (0, 0, 0, 0, 0) nr_free_pages 146583 nr_zone_inactive_anon 35 nr_zone_active_anon 11422 nr_zone_inactive_file 64699 nr_zone_active_file 120441 nr_zone_unevictable 1352 nr_zone_write_pending 0
三、為什么剩余內存很多的情況下,也會發生 Swap 呢?
這正是處理器的 NUMA (Non-Uniform Memory Access)架構導致的。
在 NUMA 架構下,多個處理器被划分到不同 Node 上,且每個 Node 都擁有自己的本地內存空間。
而通一個Node內部的內存空間實際上可以進一步分為不同的內存域。比如直接內存訪問區域、普通內存區,偽內存去等如下圖所示
1、通過numactl查詢node的分布情況
root@openstack:~# numactl --hardware available: 1 nodes (0) node 0 cpus: 0 1 node 0 size: 4976 MB node 0 free: 4088 MB node distances: node 0 0: 10
1、NUMA和swap什么關系?
1、三個內存閾值(頁最小閾值、頁低閾值和頁高閾值)查詢
cat /proc/zoneinfo Node 0, zone Normal pages free 146583 min 4986 low 6232 high 7478 spanned 399872 present 399872 managed 373102 protection: (0, 0, 0, 0, 0) nr_free_pages 146583 nr_zone_inactive_anon 35 nr_zone_active_anon 11422 nr_zone_inactive_file 64699 nr_zone_active_file 120441 nr_zone_unevictable 1352 nr_zone_write_pending 0
1、pages 處的 min、low、high,就是上面提到的三個內存閾值,而 free 是剩余內存頁數,它跟后面的nr_free_pages 相同
2、nr_zone_active_anon 和 nr_zone_inactive_anon,分別是活躍和非活躍的一名頁數
3、nr_zone_active_file 和 nr_zone_inactive_anon,分別是活躍和非活躍的文件頁數
從這個輸出結果可以發現,剩余內存遠大於高閾值,所以此時的不會回收內存
2、Node尋找空閑內存還是本地內存中回收內存?
root@openstack:~# cat /proc/sys/vm/zone_reclaim_mode 0
默認的0,也就是剛剛提到的模式,表示既可以從其他Node尋找空閑內存,也可以從本地回收內存
1、1、2、4都表示只回收本地內存,
2、2表示可以回寫臟數據回收內存
3、4表示可以用方式回收
3、到底該先回收哪一種呢?
1、對文件頁的回收
當然就是直接回收緩存,或者把臟頁寫回磁盤后再回收
2、而對匿名頁的回收
其實就是通過 Swap 機制,把它們寫入磁盤后再釋放內存
root@openstack:~# cat /proc/sys/vm/swappiness 60
swappiness 的范圍是 0-100,數值越大,越積極使用Swap,更傾向於回收匿名頁;
也就是更傾向於回收匿名頁;數值越小,越消極使用 Swap,也就是更傾向於回收文件頁
雖然swappiness的范圍是0-100,不過要注意,這並不是內存的百分比,而是Swap調整積極程度的權重
即使你把它設置成0,當剩余內存+文件頁小於也高閾值時,還是會發生Swap