【操作系統之十】內存分頁管理與swap


一、虛擬內存
電腦里內存分內存條(這里我們叫物理內存)和硬盤,內存條保存程序運行時數據,硬盤持久保存數據。那么虛擬內存是什么?

程序運行會啟動一個進程,進程里有程序段、全局數據、棧和堆,這些都會加載到內存里,每一部分都有對應的內存地址,進程就是一直在處理這些地址中數據。
然而在Linux下,進程不能直接讀寫內存地址。
進程中能訪問的地址,只能是虛擬內存地址(virtual memory address)。
操作系統會把虛擬內存地址翻譯成真實的內存地址。
這種內存管理方式,稱為虛擬內存(virtual memory)。

 

特點
1、虛擬內存地址和物理內存地址類似,都是為數據提供位置索引;
2、虛擬內存地址和物理內存地址通過映射關系來關聯;
3、不同進程都有自己的一套虛擬內存地址,用來給自己的進程空間編號;
4、進程的虛擬內存地址相互獨立。因此,兩個進程空間可以有相同的虛擬內存地址,如0x10001000。
5、應用程序的數據讀寫操作的是虛擬地址,對物理內存地址一無所知。
6、程序中表達的內存地址,也都是虛擬內存地址。
7、進程對虛擬內存地址的操作,會被操作系統翻譯成對某個物理內存地址的操作。


優勢:
1、借助虛擬內存地址,操作系統可以保障進程空間的獨立性,不同進程就不可能相互篡改對方的數據,進程出錯的可能性就大為減少。
2、有了虛擬內存地址,內存共享也變得簡單。操作系統可以把同一物理內存區域對應到多個進程空間。這樣,不需要任何的數據復制,多個進程就可以看到相同的數據。內核和共享庫的映射,就是通過這種方式進行的.


二、內存分頁
通過上面對虛擬內存的介紹得知,操作系統必須能高效地翻譯虛擬內存和物理內存地址映射。
Linux采用了分頁(paging)的方式來記錄對應關系。
所謂的分頁,就是以更大尺寸的單位頁(page)來管理內存。
內存分頁,可以極大地減少所要記錄的內存對應關系。我們已經看到,以字節為單位的對應記錄實在太多。如果把物理內存和進程空間的地址都分成頁,內核只需要記錄頁的對應關系,相關的工作量就會大為減少。
在Linux中,通常每頁大小為4KB。
使用命令查看內存頁大小:

[root@PCS101 ~]# getconf PAGE_SIZE
4096

多級分頁表

單一的連續分頁表,需要給每一個虛擬頁預留一條記錄的位置。但對於任何一個應用進程,其進程空間真正用到的地址都相當有限。我們還記得,進程空間會有棧和堆。進程空間為棧和堆的增長預留了地址,但棧和堆很少會占滿進程空間。這意味着,如果使用連續分頁表,很多條目都沒有真正用到。因此,Linux中的分頁表,采用了多層的數據結構。多層的分頁表能夠充分利用內存空間。

比如兩級分頁表:一級分頁表記錄一級表和二級表映射關系,二級表記錄二級表和物理地址映射關系。



 

三、swap
1、swap是什么?
swap字面意思是交換,指硬盤上一塊分區或者文件。
在Linux上可以使用swapon -s命令查看當前系統上正在使用的交換空間清單:

[root@PCS101 ~]# swapon -s
Filename                Type        Size    Used    Priority
/dev/dm-1                               partition    16777208    0    -1

2、swap作用

當物理內存(內存條)不夠用的時候,將部分內存上的數據交換到swap空間上,以便讓系統不會因內存不夠用而導致oom或者更致命的情況出現。
當某進程向OS請求內存發現不足時,OS會把內存中暫時不用的數據交換出去,放在SWAP分區中,這個過程稱為SWAP OUT。
當某進程又需要這些數據且OS發現還有空閑物理內存時,又會把SWAP分區中的數據交換回物理內存中,這個過程稱為SWAP IN。

3、內存回收
使用swap是內存回收機制一項實現方式。
3.1內核進行內存回收的主要原因有兩個:
(1)內核需要為任何時刻突發到來的內存申請提供足夠的內存,所以一般情況下保證有足夠的free空間對於內核來說是必要的。
(2)Linux內核使用cache的策略雖然是不用白不用,內核會使用內存中的page cache對部分文件進行緩存,以便提升文件的讀寫效率。所以內核有必要設計一個周期性回收內存的機制,以便cache的使用和其他相關內存的使用不至於讓系統的剩余內存長期處於很少的狀態。

3.2兩種內存回收機制:
(1)使用kswapd進程對內存進行周期檢查,以保證平常狀態下剩余內存盡可能夠用;
(2)直接內存回收(directpagereclaim),就是當內存分配時沒有空閑內存可以滿足要求時,觸發直接內存回收。

3.3內存回收會對兩種內存的使用進行回收:
(1)匿名內存,這部分內存沒有實際載體,不像文件緩存有硬盤文件這樣一個載體,比如典型的堆、棧數據等。這部分內存在回收的時候不能直接釋放或者寫回類似文件的媒介中,這才搞出來swap這個機制,將這類內存換出到硬盤中,需要的時候再加載出來。
(2)文件緩存,為了避免文件數據每次都要從硬盤讀取,系統會將熱點數據存儲在內存中,提高性能。如果僅僅將文件讀出來,內存回收只需要釋放這部分內存即可,下次再次讀取該文件數據直接從硬盤中讀取即可(類似HBase文件緩存)。那如果不僅將文件讀出來,而且對這些緩存的文件數據進行了修改(臟數據),回收內存就需要將這部分數據文件寫會硬盤再釋放(類似MySQL文件緩存)。

3.4 swappiness
swappiness的值定義內核使用swap的積極程度,用來控制內存回收時,回收的匿名頁更多一些還是回收的file cache更多一些 。
這只是個傾向性,是指在兩個都夠用的情況下,更願意用哪個,如果不夠用了,那么該交換還是要交換
默認值是60,可以的取值范圍是0-100;
值越高,內核就會越積極的使用swap;值越低,就會降低對swap的使用積極性;
如果swappiness設置為0,盡量少用swap,但並代表不用,如果不夠用了,那么該交換還是要交換;
如果swappiness設置為100,那么匿名頁和文件將用同樣的優先級進行回收。

[root@PCS101 ~]# cat /proc/sys/vm/swappiness
60

3.5、內存回收策略參數:zone_reclaim_mode這個參數定義了NUMA架構下不同的內存回收策略,

echo 0 > /proc/sys/vm/zone_reclaim_mode:在local內存不夠用的情況下可以去其他的內存區域分配內存;
echo 1 > /proc/sys/vm/zone_reclaim_mode:表示打開zone_reclaim模式,在local內存不夠用的情況下本地先回收再分配;
echo 2 > /proc/sys/vm/zone_reclaim_mode:本地回收盡可能先回收文件緩存對象;在本地回收內存時,可以將cache中的臟數據寫回硬盤,以回收內存。
echo 4 > /proc/sys/vm/zone_reclaim_mode:可以用swap方式回收內存。

3.6 kswapd周期檢查和內存標記水位線
Linux內核使用水位標記(watermark)的概念來描述內存壓力情況,三種內存水位標記:high、low、min
(1)剩余內存在high以上表示內存剩余較多,目前內存使用壓力不大;
(2)high-low的范圍表示目前剩余內存存在一定壓力;
(3)low-min表示內存開始有較大使用壓力,剩余內存不多了;
(4)min是最小的水位標記,當剩余內存達到這個狀態時,就說明內存面臨很大壓力。
(5)小於min這部分內存,內核是保留給特定情況下使用的,一般不會分配。

所有的內存watermark標記都是根據當前內存總大小和一個可調參數進行運算得來的,這個參數是:/proc/sys/vm/min_free_kbytes

內存回收行為就是基於剩余內存的水位標記進行決策的:
當系統剩余內存低於watermark[low]的時候,內核的kswapd開始起作用,進行內存回收。直到剩余內存達到watermark[high]的時候停止。
如果內存消耗導致剩余內存達到了或超過了watermark[min]時,就會觸發直接回收(direct reclaim)。

4、swap優先級
在使用多個swap分區或者文件的時候,還有一個優先級的概念(Priority)。
在swapon的時候,我們可以使用-p參數指定相關swap空間的優先級,值越大優先級越高,可以指定的數字范圍是-1到32767。
內核在使用swap空間的時候總是先使用優先級高的空間,后使用優先級低的。

5、數據庫系統討厭swap
swap機制的初衷是為了緩解物理內存用盡而選擇直接粗暴OOM進程的尷尬。但幾乎所有數據庫對swap都不怎么待見,無論MySQL、Oracal、MongoDB抑或HBase,為什么?
(1)數據庫系統一般都對響應延遲比較敏感,如果使用swap代替內存,數據庫服務性能必然不可接受。對於響應延遲極其敏感的系統來講,延遲太大和服務不可用沒有任何區別,比服務不可用更嚴重的是,swap場景下進程就是不死,這就意味着系統一直不可用……再想想如果不使用swap直接oom,是不是一種更好的選擇,這樣很多高可用系統直接會主從切換掉,用戶基本無感知。
(2)對於諸如HBase這類分布式系統來說,其實並不擔心某個節點宕掉,而恰恰擔心某個節點夯住。一個節點宕掉,最多就是小部分請求短暫不可用,重試即可恢復。但是一個節點夯住會將所有分布式請求都夯住,服務器端線程資源被占用不放,導致整個集群請求阻塞,甚至集群被拖垮。

 

參考:
Linux的內存分頁管理
linux內存管理swap分區

Linux Swap的那些事

Linux SWAP詳解

Linux swap分區


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM