基于內(nèi)核源碼v5.14
Linux中物理內(nèi)存的每個zone都有其自己的zone_watermarks,如下圖所示,主要有三個限值,分別為:MIN,LOW和HIGH。

一、min值的取值

如圖所示,是內(nèi)核中關(guān)于min_free_kbytes的取值的函數(shù)代碼,單位為k。
min_free_kbytes是系統(tǒng)的保留內(nèi)存的數(shù)量(以KB為單位),或者稱之為保留池大小,主要用于保證一些類似于原子內(nèi)存分配請求不會因為內(nèi)存不足而阻塞。
可以看出,其取值是當(dāng)前可用內(nèi)存的總和(KB)與16的乘積的開方,結(jié)果以K為單位。
比如,加入當(dāng)前可用內(nèi)存為4GB,那么就是4M*KB,
就是對4M*16做開方,即8K*KB,即8MB。
當(dāng)然,算出來的值并不是最終值,其規(guī)定的最大值和最小值。如圖所示,最小值為128K,最大值為256M。

后續(xù),每個zone中有關(guān)于水位min的設(shè)置,則是根據(jù)上面求得的保留內(nèi)存的大小進(jìn)行按比例分配。
二、low和high的取值
low和high的取值則取決于min的值。


這里的計算包含一個叫做"watermark_scale_factor"的系數(shù),其默認(rèn)值為10,對應(yīng)內(nèi)存占比0.1%(10/10000),可通過"/proc/ sys/vm/watermark_scale_factor"設(shè)置,最大為1000。當(dāng)它的值被設(shè)定為1000時,如圖中所示的tmp參數(shù)即為內(nèi)存大小的10%(1000/10000)。
這樣low就是在min的基礎(chǔ)上加一個tmp。
high是在min的基礎(chǔ)上加一個tmp,即在min的基礎(chǔ)上加兩個tmp。
三、內(nèi)存回收與水位
(以下內(nèi)容來自參考鏈接)
在進(jìn)行內(nèi)存分配的時候,如果分配器(比如buddy allocator)發(fā)現(xiàn)當(dāng)前空余內(nèi)存的值低于"low"但高于"min",說明現(xiàn)在內(nèi)存面臨一定的壓力,那么在此次內(nèi)存分配完成后,kswapd將被喚醒,以執(zhí)行內(nèi)存回收操作。在這種情況下,內(nèi)存分配雖然會觸發(fā)內(nèi)存回收,但不存在被內(nèi)存回收所阻塞的問題,兩者的執(zhí)行關(guān)系是異步的(之前的kswapd實現(xiàn)是周期性觸發(fā))。
這里所說的"空余內(nèi)存"其實是一個zone總的空余內(nèi)存減去其lowmem_reserve的值。對于kswapd來說,要回收多少內(nèi)存才算完成任務(wù)呢?只要把空余內(nèi)存的大小恢復(fù)到"high"對應(yīng)的watermark值就可以了,當(dāng)然,這取決于當(dāng)前空余內(nèi)存和"high"值之間的差距,差距越大,需要回收的內(nèi)存也就越多。"low"可以被認(rèn)為是一個警戒水位線,而"high"則是一個安全的水位線。

如果內(nèi)存分配器發(fā)現(xiàn)空余內(nèi)存的值低于了"min",說明現(xiàn)在內(nèi)存嚴(yán)重不足。這里要分兩種情況來討論,一種是默認(rèn)的操作,此時分配器將同步等待內(nèi)存回收完成,再進(jìn)行內(nèi)存分配,也就是direct reclaim。還有一種特殊情況,如果內(nèi)存分配的請求是帶了PF_MEMALLOC標(biāo)志位的,并且現(xiàn)在空余內(nèi)存的大小可以滿足本次內(nèi)存分配的需求,那么也將是先分配,再回收。
那誰有這樣的權(quán)利,可以在內(nèi)存嚴(yán)重短缺的時候,不等待回收而強行分配內(nèi)存呢?其中的一個人物就是kswapd啦,因為kswapd本身就是負(fù)責(zé)回收內(nèi)存的,它只需要占用一小部分內(nèi)存支撐其正常運行(就像啟動資金一樣),就可以去回收更多的內(nèi)存(賺更多的錢回來)。
雖然kswapd是在"low"到"min"的這段區(qū)間被喚醒加入調(diào)度隊列的,但當(dāng)它真正執(zhí)行的時候,空余內(nèi)存的值可能已經(jīng)掉到"min"以下了??梢?,"min"值存在的一個意義是保證像kswapd這樣的特殊任務(wù)能夠在需要的時候立刻獲得所需內(nèi)存。

在內(nèi)存分配時,只有"low"與"min"之間之間的這段區(qū)域才是kswapd的活動空間,低于了"min"會觸發(fā)direct reclaim,高于了"low"又不會喚醒kswapd。
參考鏈接:
1. Linux內(nèi)存調(diào)節(jié)之zone watermark :https://zhuanlan.zhihu.com/p/73539328