Linux內(nèi)核參數(shù)min_free_kbytes與lowmem_reserve_ratio是怎樣的

Linux內(nèi)核參數(shù)min_free_kbytes與lowmem_reserve_ratio是怎樣的,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比羅平網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式羅平網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋羅平地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。

1. min_free_kbytes

先看官方解釋:
This is used to force the Linux VM to keep a minimum number of kilobytes free. The VM uses this number to compute a watermark[WMARK_MIN] value for each lowmem zone in the system. Each lowmem zone gets a number of reserved free pages based proportionally on
its size.
Some minimal amount of memory is needed to satisfy PF_MEMALLOC allocations; if you set this to lower than 1024KB, your system will become subtly broken, and prone to deadlock under high loads.
Setting this too high will OOM your machine instantly.

解釋已經(jīng)很清楚了,主要有以下幾個關(guān)鍵點:
1. 代表系統(tǒng)所保留空閑內(nèi)存的最低限。
在系統(tǒng)初始化時會根據(jù)內(nèi)存大小計算一個默認值,計算規(guī)則是:

  min_free_kbytes = sqrt(lowmem_kbytes * 16) = 4 * sqrt(lowmem_kbytes)(注:lowmem_kbytes即可認為是系統(tǒng)內(nèi)存大?。?/pre>

另外,計算出來的值有最小最大限制,最小為128K,最大為64M。
可以看出,min_free_kbytes隨著內(nèi)存的增大不是線性增長,comments里提到了原因“because network bandwidth does not increase linearly with machine size”。隨著內(nèi)存的增大,沒有必要也線性的預留出過多的內(nèi)存,能保證緊急時刻的使用量便足矣。

2.min_free_kbytes的主要用途是計算影響內(nèi)存回收的三個參數(shù) watermark[min/low/high]
1) watermark[high] > watermark [low] > watermark[min],各個zone各一套
2)在系統(tǒng)空閑內(nèi)存低于 watermark[low]時,開始啟動內(nèi)核線程kswapd進行內(nèi)存回收(每個zone一個),直到該zone的空閑內(nèi)存數(shù)量達到watermark[high]后停止回收。如果上層申請內(nèi)存的速度太快,導致空閑內(nèi)存降至watermark[min]后,內(nèi)核就會進行direct reclaim(直接回收),即直接在應用程序的進程上下文中進行回收,再用回收上來的空閑頁滿足內(nèi)存申請,因此實際會阻塞應用程序,帶來一定的響應延遲,而且可能會觸發(fā)系統(tǒng)OOM。這是因為watermark[min]以下的內(nèi)存屬于系統(tǒng)的自留內(nèi)存,用以滿足特殊使用,所以不會給用戶態(tài)的普通申請來用。
3)三個watermark的計算方法:

 watermark[min] = min_free_kbytes換算為page單位即可,假設(shè)為min_free_pages。(因為是每個zone各有一套watermark參數(shù),實際計算效果是根據(jù)各個zone大小所占內(nèi)存總大小的比例,而算出來的per zone min_free_pages)
 watermark[low] = watermark[min] * 5 / 4
 watermark[high] = watermark[min] * 3 / 2

所以中間的buffer量為 high - low = low - min = per_zone_min_free_pages * 1/4。因為min_free_kbytes = 4* sqrt(lowmem_kbytes),也可以看出中間的buffer量也是跟內(nèi)存的增長速度成開方關(guān)系。
4)可以通過/proc/zoneinfo查看每個zone的watermark
例如:

Node 0, zone      DMA
pages free     3960
       min      65
       low      81
       high     97


3.min_free_kbytes大小的影響
min_free_kbytes設(shè)的越大,watermark的線越高,同時三個線之間的buffer量也相應會增加。這意味著會較早的啟動kswapd進行回收,且會回收上來較多的內(nèi)存(直至watermark[high]才會停止),這會使得系統(tǒng)預留過多的空閑內(nèi)存,從而在一定程度上降低了應用程序可使用的內(nèi)存量。極端情況下設(shè)置min_free_kbytes接近內(nèi)存大小時,留給應用程序的內(nèi)存就會太少而可能會頻繁地導致OOM的發(fā)生。
min_free_kbytes設(shè)的過小,則會導致系統(tǒng)預留內(nèi)存過小。kswapd回收的過程中也會有少量的內(nèi)存分配行為(會設(shè)上PF_MEMALLOC)標志,這個標志會允許kswapd使用預留內(nèi)存;另外一種情況是被OOM選中殺死的進程在退出過程中,如果需要申請內(nèi)存也可以使用預留部分。這兩種情況下讓他們使用預留內(nèi)存可以避免系統(tǒng)進入deadlock狀態(tài)。

2. lowmem_reserve_ratio

官方解釋:
For some specialised workloads on highmem machines it is dangerous for the kernel to allow process memory to be allocated from the "lowmem"zone. This is because that memory could then be pinned via the mlock() system call, or by unavailability of swapspace.
And on large highmem machines this lack of reclaimable lowmem memory can be fatal.
So the Linux page allocator has a mechanism which prevents allocations which _could_ use highmem from using too much lowmem. This means that a certain amount of lowmem is defended from the possibility of being captured into pinned user memory.
The `lowmem_reserve_ratio' tunable determines how aggressive the kernel is in defending these lower zones.
If you have a machine which uses highmem or ISA DMA and your applications are using mlock(), or if you are running with no swap then you probably should change the lowmem_reserve_ratio setting.

1.作用
除了min_free_kbytes會在每個zone上預留一部分內(nèi)存外,lowmem_reserve_ratio是在各個zone之間進行一定的防衛(wèi)預留,主要是防止高端zone在沒內(nèi)存的情況下過度使用低端zone的內(nèi)存資源。
例如現(xiàn)在常見的一個node的機器有三個zone: DMA,DMA32和NORMAL。DMA和DMA32屬于低端zone,內(nèi)存也較小,如96G內(nèi)存的機器兩個zone總和才1G左右,NORMAL就相對屬于高端內(nèi)存(現(xiàn)在一般沒有HIGH zone),而且數(shù)量較大(>90G)。低端內(nèi)存有一定的特殊作用比如發(fā)生DMA時只能分配DMA zone的低端內(nèi)存,因此需要在 盡量可以使用高端內(nèi)存時 而 不使用低端內(nèi)存,同時防止高端內(nèi)存分配不足的時候搶占稀有的低端內(nèi)存。

2. 計算方法

cat /proc/sys/vm/lowmem_reserve_ratio
256     256     32


內(nèi)核利用上述的protection數(shù)組計算每個zone的預留page量,計算出來也是數(shù)組形式,從/proc/zoneinfo里可以查看:

Node 0, zone      DMA
 pages free     1355
       min      3
       low      3
       high     4
       :
       :
   numa_other   0
       protection: (0, 2004, 2004, 2004)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 pagesets
   cpu: 0 pcp: 0
       :

在進行內(nèi)存分配時,這些預留頁數(shù)值和watermark相加來一起決定現(xiàn)在是滿足分配請求,還是認為空閑內(nèi)存量過低需要啟動回收。
例如,如果一個normal區(qū)(index = 2)的頁申請來試圖分配DMA區(qū)的內(nèi)存,且現(xiàn)在使用的判斷標準是watermark[low]時,內(nèi)核計算出 page_free = 1355,而watermark + protection[2] = 3 + 2004 = 2007 > page_free,則認為空閑內(nèi)存太少而不予以分配。如果分配請求本就來自DMA zone,則 protection[0] = 0會被使用,而滿足分配申請。

zone[i] 的 protection[j] 計算規(guī)則如下:

(i < j):
 zone[i]->protection[j]
 = (total sums of present_pages from zone[i+1] to zone[j] on the node)
   / lowmem_reserve_ratio[i];
(i = j):
  (should not be protected. = 0;
(i > j):
  (not necessary, but looks 0)

默認的 lowmem_reserve_ratio[i] 值是:

   256 (if zone[i] means DMA or DMA32 zone)
   32  (others).

從上面的計算規(guī)則可以看出,預留內(nèi)存值是ratio的倒數(shù)關(guān)系,如果是256則代表 1/256,即為 0.39% 的高端zone內(nèi)存大小。
如果想要預留更多頁,應該設(shè)更小一點的值,最小值是1(1/1 -> 100%)。

3. 和min_free_kbytes(watermark)的配合示例
下面是一段某線上服務(wù)器(96G)內(nèi)存申請失敗時打印出的log:

[38905.295014] java: page allocation failure. order:1, mode:0x20, zone 2
[38905.295020] Pid: 25174, comm: java Not tainted 2.6.32-220.23.1.tb750.el5.x86_64 #1
...
[38905.295348] active_anon:5730961 inactive_anon:216708 isolated_anon:0
[38905.295349]  active_file:2251981 inactive_file:15562505 isolated_file:0
[38905.295350]  unevictable:1256 dirty:790255 writeback:0 unstable:0
[38905.295351]  free:113095 slab_reclaimable:577285 slab_unreclaimable:31941
[38905.295352]  mapped:7816 shmem:4 pagetables:13911 bounce:0
[38905.295355] Node 0 DMA free:15796kB min:4kB low:4kB high:4kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB  isolated(anon):0kB isolated(file):0kB present:15332kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[38905.295365] lowmem_reserve[]: 0 1951 96891 96891
[38905.295369] Node 0 DMA32 free:380032kB min:800kB low:1000kB high:1200kB active_anon:46056kB inactive_anon:10876kB active_file:15968kB inactive_file:129772kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1998016kB mlocked:0kB dirty:20416kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:11716kB slab_unreclaimable:160kB kernel_stack:176kB pagetables:112kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:576 all_unreclaimable? no
[38905.295379] lowmem_reserve[]: 0 0 94940 94940
[38905.295383] Node 0 Normal free:56552kB min:39032kB low:48788kB high:58548kB active_anon:22877788kB inactive_anon:855956kB active_file:8991956kB inactive_file:62120248kB unevictable:5024kB isolated(anon):0kB isolated(file):0kB present:97218560kB mlocked:5024kB dirty:3140604kB writeback:0kB mapped:31264kB shmem:16kB slab_reclaimable:2297424kB slab_unreclaimable:127604kB kernel_stack:12528kB pagetables:55532kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[38905.295393] lowmem_reserve[]: 0 0 0 0
[38905.295396] Node 0 DMA: 1*4kB 2*8kB 0*16kB 1*32kB 2*64kB 0*128kB 1*256kB 0*512kB 1*1024kB 1*2048kB 3*4096kB = 15796kB
[38905.295405] Node 0 DMA32: 130*4kB 65*8kB 75*16kB 72*32kB 95*64kB 22*128kB 10*256kB 7*512kB 4*1024kB 2*2048kB 86*4096kB = 380032kB
[38905.295414] Node 0 Normal: 12544*4kB 68*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 54816kB
[38905.295423] 17816926 total pagecache pages

1)從第一行l(wèi)og“order:1, mode:0x20”可以看出來是GFP_ATOMIC類型的申請,且order = 1(page = 2 )

2)第一次內(nèi)存申請嘗試
在__alloc_pages_nodemask()里,首先調(diào)用 get_page_from_freelist() 嘗試第一次申請,使用的標志位是 ALLOC_WMARK_LOW|ALLOC_CPUSET,它會對每個zone都做 zone_watermark_ok()的檢查,使用的就是傳進的watermark[low]閾值。
在zone_watermark_ok()里會考慮z->lowmem_reserve[],導致在normal上的申請不會落到低端zone。比如對于DMA32:

free pages = 380032KB = 95008 pages < low(1000KB = 250 pages) +  lowmem_reserve[normal](94940) = 95190

所以就認為DMA32也不平不ok,同理更用不了DMA的內(nèi)存。
而對于normal自己內(nèi)存來說,free pages = 56552 KB = 14138 pages,也不用考慮lowmem_reserve(0),但這時還會考慮申請order(1),減去order 0的12544個page后只剩 14138 - 12544 = 1594,也小于 low / 2 = (48788KB=12197pages) / 2 = 6098 pages。
所以初次申請嘗試失敗,進入__alloc_pages_slowpath() 嘗試進行更為積極一些的申請。

3)第二次內(nèi)存申請嘗試
__alloc_pages_slowpath()首先是通過 gfp_to_alloc_flags() 修改alloc_pages,設(shè)上更為強硬的標志位。這塊根據(jù)原來的GFP_ATOMIC會設(shè)上 ALLOC_WMARK_MIN | ALLOC_HARDER | ALLOC_HIGH。但注意的是不會設(shè)上 ALLOC_NO_WATERMARKS 標志位。這個標志位不再判斷zone的水位限制,屬于優(yōu)先級最高的申請,可以動用所有的reserve內(nèi)存,但條件是(!in_interrupt() && ((p->flags
& PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE)))),即要求不能在中斷上下文,且是正在進行回收(例如kswapd)或者正在退出的進程。

之后進入拿著新的alloc_pages重新進入get_page_from_pagelist() 嘗試第二次申請,雖然有了 ALLOC_HARDER和ALLOC_HIGH,但是不幸的是在3個zone的zone_watermark_ok檢查中還是都無法通過,例如對于DMA32:

free pages = 380032KB = 95008 pages
因為設(shè)上了ALLOC_HIGH 所以會將得到的watermark[min]減半,即min = min/2 = 800K / 2 = 400K = 100pages
而又因為設(shè)上了ALLOC_HARDER,會再將min砍去1/4,即min = 3 * min / 4 = 100 pages * 3 / 4 = 75 pages
即便如此,min(75 pages) +  lowmem_reserve[normal](94940) = 95015,仍大于free pages,仍認為無法分配內(nèi)存,同理DMA也不不成功,而normal中 free pages里連續(xù)8K的頁太少也無法滿足分配

第二次失敗后,由于沒有ALLOC_NO_WATERMARK也不會進入__alloc_pages_high_priority 進行最高優(yōu)先級的申請,同時由于是GFP_ATOMIC類型的分配不能阻塞回收或者進入OOM,因此就以申請失敗告終。

遇到此種情況可以適當調(diào)高 min_free_kbytes 使kswapd較早啟動回收,使系統(tǒng)一直留有較多的空閑內(nèi)存,同時可以適度降低 lowmem_reserve_ratio(可選),使得內(nèi)存不足的情況下(主要是normal zone)可以借用DMA32/DMA的內(nèi)存救急(注意不能也不能過低)。

看完上述內(nèi)容,你們掌握Linux內(nèi)核參數(shù)min_free_kbytes與lowmem_reserve_ratio是怎樣的的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

網(wǎng)頁名稱:Linux內(nèi)核參數(shù)min_free_kbytes與lowmem_reserve_ratio是怎樣的
網(wǎng)頁鏈接:http://muchs.cn/article8/ghicop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站營銷、Google、關(guān)鍵詞優(yōu)化App設(shè)計、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化