自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux 內(nèi)存管理的水位控制

系統(tǒng) Linux
在講分區(qū)頁(yè)框分配器分配內(nèi)存的時(shí)候,進(jìn)入伙伴算法前用函數(shù)zone_watermark_fast(),來根據(jù)水位來判斷當(dāng)前內(nèi)存情況。內(nèi)存夠的話采用伙伴算法分配,不夠的話通過 node_reclaim 回收內(nèi)存。

[[401801]]

本文轉(zhuǎn)載自微信公眾號(hào)「人人都是極客」,作者布道師Peter 。轉(zhuǎn)載本文請(qǐng)聯(lián)系人人都是極客公眾號(hào)。

分區(qū)頁(yè)框分配器之水位

在講分區(qū)頁(yè)框分配器分配內(nèi)存的時(shí)候,進(jìn)入伙伴算法前用函數(shù)zone_watermark_fast(),來根據(jù)水位來判斷當(dāng)前內(nèi)存情況。內(nèi)存夠的話采用伙伴算法分配,不夠的話通過 node_reclaim 回收內(nèi)存。

水位的初始化

先看下水位的初始化:

  1. int __meminit init_per_zone_wmark_min(void) 
  2.         unsigned long lowmem_kbytes; 
  3.         int new_min_free_kbytes; 
  4.  
  5.         lowmem_kbytes = nr_free_buffer_pages() * (PAGE_SIZE >> 10);      ------ (1)   
  6.         new_min_free_kbytes = int_sqrt(lowmem_kbytes * 16); 
  7.  
  8.         if (new_min_free_kbytes > user_min_free_kbytes) { 
  9.                 min_free_kbytes = new_min_free_kbytes;                   ------ (2) 
  10.                 if (min_free_kbytes < 128) 
  11.                         min_free_kbytes = 128; 
  12.                 if (min_free_kbytes > 65536) 
  13.                         min_free_kbytes = 65536; 
  14.         } else { 
  15.                 pr_warn("min_free_kbytes is not updated to %d because user defined value %d is preferred\n"
  16.                                 new_min_free_kbytes, user_min_free_kbytes); 
  17.         } 
  18.         setup_per_zone_wmarks();                                         ------ (3) 
  19.         refresh_zone_stat_thresholds(); 
  20.         setup_per_zone_lowmem_reserve();                                 ------ (4) 
  21.  
  22. #ifdef CONFIG_NUMA 
  23.         setup_min_unmapped_ratio(); 
  24.         setup_min_slab_ratio(); 
  25. #endif 
  26.  
  27.         return 0; 
  28. core_initcall(init_per_zone_wmark_min) 

(1). nr_free_buffer_pages 是獲取ZONE_DMA和ZONE_NORMAL區(qū)中高于high水位的總頁(yè)數(shù)nr_free_buffer_pages = managed_pages - high_pages

(2). min_free_kbytes 是總的min大小,min_free_kbytes = 4 * sqrt(lowmem_kbytes)

(3). setup_per_zone_wmarks 根據(jù)總的min值,再加上各個(gè)zone在總內(nèi)存中的占比,然后通過do_div就計(jì)算出他們各自的min值,進(jìn)而計(jì)算出各個(gè)zone的水位大小。min,low,high的關(guān)系:low = min *125%,high = min * 150%。min,low,high之間的比例關(guān)系與 watermark_scale_factor 相關(guān)??梢酝ㄟ^ /proc/sys/vm/watermark_scale_factor 設(shè)置

(4). setup_per_zone_lowmem_reserve 設(shè)置每個(gè)zone的lowmem_reserve大小。lowmem_reserve值可以通過 /proc/sys/vm/lowmem_reserve_ratio 來修改。

為什么需要設(shè)置每個(gè)zone的保留內(nèi)存呢,lowmem_reserve的作用是什么?

我們知道內(nèi)核在分配內(nèi)存時(shí),會(huì)按照 HIGHMEM->NORMAL->DMA 的方向進(jìn)行遍歷,如果當(dāng)前Zone分配失敗,就會(huì)嘗試下一個(gè)低級(jí)的Zone。我們可以想像應(yīng)用進(jìn)程通過內(nèi)存映射申請(qǐng) HIGHMEM,如果此時(shí)HIGHMEM Zone無法滿足分配,則會(huì)嘗試從 NORMAL 進(jìn)行分配。這就有一個(gè)問題,來自 HIGHMEM Zone 的請(qǐng)求可能會(huì)耗盡 NORMAL Zone 的內(nèi)存,最終的結(jié)果就是 NORMAL Zone 無內(nèi)存提供給內(nèi)核的正常分配。

因此針對(duì)這個(gè)場(chǎng)景,可以通過保留內(nèi)存 lowmem_reserve[NORMAL] 給 NORMAL Zone 自己使用。

同樣當(dāng)從NORMAL Zone失敗后,會(huì)嘗試從zonelist中的DMA Zone申請(qǐng),通過lowmem_reserve[DMA],限制來自HIGHMEM和NORMAL的分配請(qǐng)求。

  1. $ cat /proc/sys/vm/lowmem_reserve_ratio 
  2. 256     32      
  1. $ cat /proc/zoneinfo 
  2. Node 0, zone    DMA32 
  3.     ...... 
  4.     pages free     361678 
  5.         min      674 
  6.         low      2874 
  7.         high     3314 
  8.         spanned  523776 
  9.         present  496128 
  10.         managed  440432 
  11.         protection: (0, 3998, 3998) 
  12.     ...... 
  13. Node 0, zone   Normal 
  14.     pages free     706981 
  15.         min      1568 
  16.         low      6681 
  17.         high     7704 
  18.         spanned  8912896 
  19.         present  1048576 
  20.         managed  1023570 
  21.         protection: (0, 0, 0) 
  22.     ...... 
  23. Node 0, zone  Movable 
  24.   pages free     0 
  25.         min      0 
  26.         low      0 
  27.         high     0 
  28.         spanned  0 
  29.         present  0 
  30.         managed  0 
  31.         protection: (0, 0, 0) 
  • spanned:表示當(dāng)前zone所包含的所有的pages
  • present:表示當(dāng)前zone在去掉第一階段kernel reserve的內(nèi)存之后剩下的pages
  • managed:表示當(dāng)前zone去掉初始化完成以后所有的kernel reserve的內(nèi)存剩下的pages

結(jié)合上面arm64平臺(tái)的數(shù)值舉個(gè)例子,假設(shè)這2個(gè)Zones分別包含440432, 1023570個(gè)pages(實(shí)際是/proc/zoneinfo里字段managed的值)。如下圖所示,使用每個(gè)區(qū)域的 managed pages 和 lowmem_reserve_ratio 計(jì)算每個(gè)區(qū)域的lowmem_reserve值,可以看出結(jié)果和protection值一樣。

水位的判斷

從這張圖可以看出:

 

  • 如果空閑頁(yè)數(shù)目min值,則該zone非常缺頁(yè),頁(yè)面回收壓力很大,應(yīng)用程序?qū)憙?nèi)存操作就會(huì)被阻塞,直接在應(yīng)用程序的進(jìn)程上下文中進(jìn)行回收,即direct reclaim。
  • 如果空閑頁(yè)數(shù)目小于low值,kswapd線程將被喚醒。默認(rèn)情況下,low值為min值的125%,可以通過修改watermark_scale_factor來改變比例值
  • 如果空閑頁(yè)面的值大于high值,kswapd線程將睡眠。默認(rèn)情況下,high值為min值的150%,可以通過修改watermark_scale_factor來改變比例值

 

責(zé)任編輯:武曉燕 來源: 人人都是極客
相關(guān)推薦

2013-10-11 17:32:18

Linux運(yùn)維內(nèi)存管理

2020-07-28 08:10:33

Linux內(nèi)存虛擬

2009-12-25 15:24:16

內(nèi)存管理

2021-03-17 21:34:44

Linux內(nèi)存管理

2023-10-18 13:31:00

Linux內(nèi)存

2009-10-20 16:35:26

Linux內(nèi)存管理

2022-08-08 08:31:00

Linux內(nèi)存管理

2017-05-18 16:30:29

Linux內(nèi)存管理

2023-07-06 00:45:05

Linux保護(hù)模式

2009-08-17 08:32:56

Linux操作系統(tǒng)內(nèi)存管理Linux

2009-12-25 17:15:03

Linux內(nèi)存

2020-04-08 09:20:25

Linux內(nèi)存系統(tǒng)

2020-06-28 09:30:37

Linux內(nèi)存操作系統(tǒng)

2024-05-06 08:09:10

Linux內(nèi)存管理

2018-08-09 16:32:49

內(nèi)存管理框架

2022-02-11 07:45:10

Linuxsmem系統(tǒng)

2013-09-29 15:11:46

Linux運(yùn)維內(nèi)存管理

2013-10-12 13:01:51

Linux運(yùn)維內(nèi)存管理

2025-03-26 00:00:05

2025-01-02 11:06:22

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)