2016-07-31 26 views
1

內核文檔中的過度提交文章只是提到過載模式0基於啓發式提交處理。它沒有概述涉及的啓發式。Linux over commit heuristic

有人可以闡明真正的啓發式是什麼?任何與內核源碼相關的鏈接都可以工作!

在此先感謝

+0

而你的問題是? – Li357

+0

什麼是啓發式? – KodeWarrior

回答

3

其實,過量使用會計的內核文檔有一些細節:https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

Linux內核支持以下過量使用處理模式

0 - 啓發式過量使用處理。

明顯的地址空間過量使用被拒絕。用於典型系統。它確保了嚴重的分配失敗,同時允許過量使用 以減少交換使用。允許root在這種模式下分配稍多的內存。這是默認設置。

另外Documentation/sysctl/vm.txt

overcommit_memory: 此值包含一個標誌,使內存過度。
當該標誌爲0時,內核將嘗試估計 免費的記憶中留下當用戶空間的請求更多的內存量...

見文檔/ VM /過量使用,會計和 毫米/ mmap.c :: __ vm_enough_memory () 瞭解更多信息。

此外,man 5 proc

/proc/sys/vm/overcommit_memory此文件包含內核虛擬內存會計模式。 價值觀是:

   0: heuristic overcommit (this is the default) 
       1: always overcommit, never check 
       2: always check, never overcommit 

在模式0中,mmap(2)MAP_NORESERVE呼叫不檢查,默認的檢查非常薄弱,導致得到一個過程「OOM殺死」的風險。

因此,通過啓發式方法禁用非常大的分配,但有時應用程序可能會分配比系統中物理內存大小更多的虛擬內存,如果它沒有使用全部內存。用MAP_NORESERVE可存儲內存量可能會更高。

設置爲「overcommit策略通過sysctl`vm設置。overcommit_memory」」,這樣我們就可以發現它是如何在源代碼中實現: http://lxr.free-electrons.com/ident?v=4.4;i=sysctl_overcommit_memory,在line 112 of mm/mmap.c

112 int sysctl_overcommit_memory __read_mostly = OVERCOMMIT_GUESS; /* heuristic overcommit */ 

,不斷OVERCOMMIT_GUESS(在linux/mman.h定義)定義只有在line 170 of mm/mmap.cused實際上,這是實施啓發式:

138 /* 
139 * Check that a process has enough memory to allocate a new virtual 
140 * mapping. 0 means there is enough memory for the allocation to 
141 * succeed and -ENOMEM implies there is not. 
142 * 
143 * We currently support three overcommit policies, which are set via the 
144 * vm.overcommit_memory sysctl. See Documentation/vm/overcommit-accounting 
145 * 
146 * Strict overcommit modes added 2002 Feb 26 by Alan Cox. 
147 * Additional code 2002 Jul 20 by Robert Love. 
148 * 
149 * cap_sys_admin is 1 if the process has admin privileges, 0 otherwise. 
150 * 
151 * Note this is a helper function intended to be used by LSMs which 
152 * wish to use this logic. 
153 */ 
154 int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) 
... 
170   if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { 
171     free = global_page_state(NR_FREE_PAGES); 
172     free += global_page_state(NR_FILE_PAGES); 
173 
174     /* 
175     * shmem pages shouldn't be counted as free in this 
176     * case, they can't be purged, only swapped out, and 
177     * that won't affect the overall amount of available 
178     * memory in the system. 
179     */ 
180     free -= global_page_state(NR_SHMEM); 
181 
182     free += get_nr_swap_pages(); 
183 
184     /* 
185     * Any slabs which are created with the 
186     * SLAB_RECLAIM_ACCOUNT flag claim to have contents 
187     * which are reclaimable, under pressure. The dentry 
188     * cache and most inode caches should fall into this 
189     */ 
190     free += global_page_state(NR_SLAB_RECLAIMABLE); 
191 
192     /* 
193     * Leave reserved pages. The pages are not for anonymous pages. 
194     */ 
195     if (free <= totalreserve_pages) 
196       goto error; 
197     else 
198       free -= totalreserve_pages; 
199 
200     /* 
201     * Reserve some for root 
202     */ 
203     if (!cap_sys_admin) 
204       free -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10); 
205 
206     if (free > pages) 
207       return 0; 
208 
209     goto error; 
210   } 

因此,啓發式是估計物理內存頁面有多少現在使用(free)的方式,當請求更多的內存爲p漫遊(申請要求pages頁)。

隨着始終啓用過量使用(「1」),此函數總是返回0(「有足夠的內存用於這個請求」)

164   /* 
165   * Sometimes we want to use more memory than we have 
166   */ 
167   if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS) 
168     return 0; 

沒有這個默認啓發式,在模式「2」,內核將盡量考慮到所請求的頁面pages獲得新Committed_AS(從/proc/meminfo):

162   vm_acct_memory(pages); 
... 

這個is actuallyvm_committed_as只是增量 - __percpu_counter_add(&vm_committed_as, pages, vm_committed_as_batch);

212   allowed = vm_commit_limit(); 

一些神奇is here:

401 /* 
402 * Committed memory limit enforced when OVERCOMMIT_NEVER policy is used 
403 */ 
404 unsigned long vm_commit_limit(void) 
405 { 
406   unsigned long allowed; 
407 
408   if (sysctl_overcommit_kbytes) 
409     allowed = sysctl_overcommit_kbytes >> (PAGE_SHIFT - 10); 
410   else 
411     allowed = ((totalram_pages - hugetlb_total_pages()) 
412       * sysctl_overcommit_ratio/100); 
413   allowed += total_swap_pages; 
414 
415   return allowed; 
416 } 
417 

所以,allowed設置了其中一個爲vm.overcommit_kbytes的sysctl或vm.overcommit_ratio物理RAM的百分比,以及交換分區的大小千字節。

213   /* 
214   * Reserve some for root 
215   */ 
216   if (!cap_sys_admin) 
217     allowed -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10); 

僅允許用於根 一些量存儲器(PAGE_SHIFT是12健康的人,PAGE_SHIFT-10是從千字節只是轉換到頁計數)。

218 
219   /* 
220   * Don't let a single process grow so big a user can't recover 
221   */ 
222   if (mm) { 
223     reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10); 
224     allowed -= min_t(long, mm->total_vm/32, reserve); 
225   } 
226 
227   if (percpu_counter_read_positive(&vm_committed_as) < allowed) 
228     return 0; 

如果在對請求進行計數之後,所有用戶空間仍然具有提交的內存量小於允許的數量,則分配它。在其他情況下,拒絕該請求(並且不要求該請求)。

229 error: 
230   vm_unacct_memory(pages); 
231 
232   return -ENOMEM; 

換句話說,作爲總結由安德里斯·布勞威爾,9內存,9.6過量使用和OOM,2003-02-01 - https://www.win.tue.nl/~aeb/linux/lk/lk-9.html 「Linux內核Linux內核的一些討論。」:

在正確的方向前進

由於30年2月5日的值是:

  • 0(默認):如前:猜測多少過量使用是合理的,
  • 1:從不拒絕任何的malloc(),
  • 2:得到準確的過量使用 - 從來沒有承諾的虛擬地址空間比交換空間,加上身體的一小部分overcommit_ratio較大記憶。

因此,「2」是的請求之後使用的存儲器量精確的計算,和「0」是啓發式估計。