一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux內存配置:overcommit的設置

Linux閱碼場 ? 來源:未知 ? 作者:胡薇 ? 2018-06-14 11:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、前言

終于可以進入Linux kernel內存管理的世界了,但是從哪里入手是一個問題,當面對一個復雜系統(tǒng)的時候,有時候不知道怎么開始。遵守“一切以人為本”的原則,我最終選擇先從從userspace的視角來看內核的內存管理。最開始的系列文章選擇了vm運行參數這個主題。執(zhí)行l(wèi)s /proc/sys/vm的命令,你可以看到所有的vm運行參數,本文選擇了overcommit相關參數來介紹。

本文的代碼來自4.0內核。

二、背景知識

要了解這類參數首先要理解什么是committed virtual memory?使用版本管理工具的工程師都熟悉commit的含義,就是向代碼倉庫提交自己更新的意思,對于這個場景,實際上就是各個進程提交自己的虛擬地址空間的請求。雖然我們總是宣稱每個進程都有自己獨立的地址空間,但素,這些地址空間都是虛擬地址,就像是鏡中花,水中月。當進程需要內存時(例如通過brk分配內存),進程從內核獲得的僅僅是一段虛擬地址的使用權,而不是實際的物理地址,進程并沒有獲得物理內存。實際的物理內存只有當進程真的去訪問新獲取的虛擬地址時,產生“缺頁”異常,從而進入分配實際物理地址的過程,也就是分配實際的page frame并建立page table。之后系統(tǒng)返回產生異常的地址,重新執(zhí)行內存訪問,一切好象沒有發(fā)生過。因此,看起來虛擬內存和物理內存的分配被分割開了,這是否意味著進程可以任意的申請?zhí)摂M地址空間呢?也不行,畢竟virtual memory需要physical memory做為支撐,如果分配了太多的virtual memory,和物理內存不成比例,對性能會有影響。對于這個狀況,我們稱之為overcommit。

三、參數介紹

1、overcommit_memory。overcommit_memory這個參數就是用來控制內核對overcommit的策略。該參數可以設定的值包括:

OVERCOMMIT_ALWAYS表示內核并不限制overcommit,無論進程們commit了多少的地址空間的申請,go ahead,do what you like,只不過后果需要您自己的負責。OVERCOMMIT_NEVER是另外的極端,永遠不要overcommit。OVERCOMMIT_GUESS的策略和其名字一樣,就是“你猜”,多么調皮的設定啊(后面代碼分析會進一步描述)。BTW,我不太喜歡這個參數的命名,更準確的命名應該類似vm_overcommit_policy什么的,大概是歷史的原因,linux kernel一直都是保持了這個符號。

2、overcommit_kbytes和overcommit_ratio

OVERCOMMIT_ALWAYS可以很任性,總是允許出現overcommit現象,但是OVERCOMMIT_NEVER不行,這種策略下,系統(tǒng)不允許出現overcommit。不過要檢查overcommit,具體如何判斷呢,總得有個標準吧,這個標準可以從vm_commit_limit這個函數看出端倪:

overcommit的標準有兩個途徑來設定,一種是直接定義overcommit_kbytes,這時候標準值是overcommit_kbytes+total_swap_pages。什么是total_swap_pages呢?這里要稍微講一下關于頁面回收(page frame reclaim)機制。

就虛擬內存和物理內存的分配策略而言,inux kernel對虛擬地址空間的分配是比較寬松的(雖然有overcommit機制),但是,kernel對用戶空間的物理內存申請(創(chuàng)建用戶空間進程、用戶空間程序的malloc(就是堆的分配),用戶空間進程stack的分配等)是非常的吝嗇的(順便提及的是:內存管理模塊對來自內核的內存申請是大方的,內核工程師的自豪感是否油然而生,呵呵~~),總是百般阻撓,直到最后一刻實在沒有辦法了才分配物理內存。這種機制其背后的思想是更好的使用內存,也就是說:在限定的物理內存資源下,可以盡量讓更多的用戶空間進程運行起來。如果讓物理地址和虛擬地址空間是一一映射的時候,那么系統(tǒng)中的可以啟動進程數目必定是受限的,進程可以申請的內存數目也是受限的,你的程序不得不經常面內存分配失敗的issue。如果你想破解這個難題,就需要將一個較小的物理內存空間映射到一個較大的各個用戶進程組成的虛擬地址空間之上。怎么辦,最簡單的方法就是“拆東墻補西墻”。感謝程序天生具備局部性原理,可以讓內核有東墻可以拆,但是,拆東墻(swap out)也是技術活,不是所有的進程虛擬空間都可以拆。比如說程序的正文段的內容就是可以拆,因為這些內存中的內容有磁盤上的程序做支撐,當再次需要的時候(補西墻),可以從磁盤上的程序文件中reload。不是所有的進程地址空間都是有file-backup的,堆、stack這些進程的虛擬地址段都是沒有磁盤文件與之對應的,也就是傳說中的anonymous page。對于anonymous page,如果我們建立swap file或者swap device,那么這些anonymous page也同樣可以被交換到磁盤,并且在需要的時候load進內存。

OK,我們回到total_swap_pages這個變量,它其實就是系統(tǒng)可以將anonymous page交換到磁盤的大小,如果我們建立32MB的swap file或者swap device,那么total_swap_pages就是(32M/page size)。

overcommit的標準的另外一個標準(在overcommit_kbytes設定為0的時候使用)是和系統(tǒng)可以使用的page frame相關。并不是系統(tǒng)中的物理內存有多少,totalram_pages就有多少,實際上很多的page是不能使用的,例如linux kernel本身的正文段,數據段等就不能計入totalram_pages,還有一些系統(tǒng)reserve的page也不算數,最終totalram_pages實際上就是系統(tǒng)可以管理分配的總內存數目。overcommit_ratio是一個百分比的數字,50表示可以使用50%的totalram_pages,當然還有考慮total_swap_pages的數目,上文已經描述。

還有一個小細節(jié)就是和huge page相關的,傳統(tǒng)的4K的page和huge page的選擇也是一個平衡問題。normal page可以靈活的管理內存段,浪費少。但是不適合大段虛擬內存段的管理(因為要建立大量的頁表,TLB side有限,因此會導致TLB miss,影響性能),huge page和normal page相反。內核可以同時支持這兩種機制,不過是分開管理的。我們本節(jié)描述的參數都是和normal page相關的,因此在計算allowed page的時候要減去hugetlb_total_pages。

3、admin_reserve_kbytes和user_reserve_kbytes

做任何事情都要留有余地,不要把自己逼到絕境。這兩個參數就是防止內存管理模塊把自己逼到絕境。

上面我們提到拆東墻補西墻的機制,但是這種機制在某些情況下其實也不能正常的運作。例如進程A在訪問自己的內存的時候,出現page fault,通過scan,將其他進程(B、C、D…)的“東墻”拆掉,分配給進程A,以便讓A可以正常運行。需要注意的是,“拆東墻”不是那么簡單的事情,有可能需要進行磁盤I/O操作(比如:將dirty的page cache flush到磁盤)。但是,系統(tǒng)很快調度到了B進程,而B進程立刻需要剛剛拆除的東墻,怎么辦?B進程立刻需要分配物理內存,如果沒有free memory,這時候也只能啟動scan過程,繼續(xù)找新的東墻。在極端的情況下,很有可能把剛剛補好的西墻拆除,這時候,整個系統(tǒng)的性能就會顯著的下降,有的時候,用戶點擊一個button,很可能半天才能響應。

面對這樣的情況,用戶當然想恢復,例如kill那個吞噬大量內存的進程。這個操作也需要內存(需要fork進程),因此,為了能夠讓用戶順利逃脫絕境,系統(tǒng)會保留user_reserve_kbytes的內存。

對于支持多用戶的GNU/linux系統(tǒng)而言,恢復系統(tǒng)可能需要root用來來完成,這時候需要保留一定的內存來支持root用戶的登錄操作,支持root進行trouble shooting(使用ps,top等命令),找到那個鬧事的進程并kill掉它。這些為root用戶操作而保留的memory定義在admin_reserve_kbytes參數中。

四、代碼分析

用戶空間進程在使用內存的時候(更準確的說是分配虛擬內存,其實用戶空間根本無法觸及物理內存的分配,那是內核的領域),內核都會調用__vm_enough_memory函數來驗證是否可以允許分配這段虛擬內存,代碼如下:

int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) { …… if (sysctl_overcommit_memory == OVERCOMMIT_ALWAYS) ----(1) return 0;

if (sysctl_overcommit_memory == OVERCOMMIT_GUESS) { free = global_page_state(NR_FREE_PAGES); free += global_page_state(NR_FILE_PAGES); free -= global_page_state(NR_SHMEM);

free += get_nr_swap_pages(); free += global_page_state(NR_SLAB_RECLAIMABLE); ------(2)

if (free <= totalreserve_pages) ------------------(3)???????????? goto error;???????? else???????????? free -= totalreserve_pages;

if (!cap_sys_admin) ----------------------(4) free -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10);

if (free > pages) ------------------------(5) return 0;

goto error; }

allowed = vm_commit_limit(); -------------------(6) if (!cap_sys_admin) allowed -= sysctl_admin_reserve_kbytes >> (PAGE_SHIFT - 10); --參考(4)的解釋

if (mm) { ----------------------------(7) reserve = sysctl_user_reserve_kbytes >> (PAGE_SHIFT - 10); allowed -= min_t(long, mm->total_vm / 32, reserve); }

if (percpu_counter_read_positive(&vm_committed_as) < allowed) ----(8)???????? return 0;

……}

(1)OVERCOMMIT_ALWAYS奏是辣么自由,隨你overcommit,只要你喜歡。return 0表示目前有充足的virtual memory資源。

(2)OVERCOMMIT_GUESS其實就是讓內核自己根據當前的狀況進行判斷,因此首先進入收集信息階段,看看系統(tǒng)有多少free page frame(NR_FREE_PAGES標記,位于Buddy system的free list中),這些是優(yōu)質資源,沒有任何的開銷就可以使用。NR_FILE_PAGES是page cache使用的page frame,主要是用戶空間進程讀寫文件造成的。這些cache都是為了加快系統(tǒng)性能而增加的,因此,如果直接操作到磁盤,本質上這些page cache都是free的。不過,這里有一個特例就是NR_SHMEM,它主要是用于進程間的share memory機制,這些shmem page frame不能認為是free的,因此要減去。get_nr_swap_pages函數返回swap file或者swap device上空閑的“page frame”數目。本質上,swap file或者swap device上的磁盤空間都是給anonymous page做騰挪之用,其實這里的“page frame”不是真的page frame,我們稱之swap page好了。get_nr_swap_pages函數返回了free swap page的數目。這里把free swap page的數目也計入free主要是因為可以把使用中的page frame swap out到free swap page上,因此也算是free page,雖然開銷大了一點。至于NR_SLAB_RECLAIMABLE,那就更應該計入free page了,因為slab對象都已經標注自己的reclaim的了,當然是free page了。

(3)要解釋totalreserve_pages需要太長的篇幅,我們這里略過,但這是一個能讓系統(tǒng)運行需要預留的page frame的數目,因此我們要從減去totalreserve_pages。如果當前free page數目小于totalreserve_pages,那么當然拒絕vm的申請。

(4)如果是普通的進程,那么還需要保留admin_reserve_kbytes的free page,以便在出問題的時候可以讓root用戶可以登錄并進行恢復操作。

(5)最關鍵的來了,比對本次申請virtual memory的page數目和當前“free”(之所以加引號表示并真正free page frame數目)的數據,如果在保留了足夠的page frame之后,還有足夠的page可以滿足本次分配,那么就批準本次vm的分配。

(6)從這里開始,進入OVERCOMMIT_NEVER的處理。從vm_commit_limit函數中可以獲取一個基本的判斷overcommit的標準,當然要根據具體情況進行調整,例如說admin_reserve_kbytes。

(7)如果是用戶空間的進程,我們還要為用戶能夠從絕境中恢復而保留一些page frame,具體保留多少需要考量兩個因素,一個是單一進程的total virtual memory,一個用戶設定的運行時參數user_reserve_kbytes。更具體的考量因素可以參考https://lkml.org/lkml/2013/3/18/812,這里就不贅述了。

(8)allowed變量保存了判斷overcommit的上限,vm_committed_as保存了當前系統(tǒng)中已經申請(包括本次)的virtual memory的數目。如果大于這個上限就判斷overcommit,本次申請virtual memory失敗。

五、參考文獻

1、Documentation/vm/overcommit-accounting

2、Documentation/sysctl/vm.txt

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11496

    瀏覽量

    213224
  • 內存
    +關注

    關注

    8

    文章

    3117

    瀏覽量

    75112

原文標題:郭健:Linux內存管理系統(tǒng)參數配置之overcommit

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Linux內存管理是什么,Linux內存管理詳解

    Linux內存管理 Linux內存管理是一個非常復雜的過程,主要分成兩個大的部分:內核的內存管理和進程虛擬
    的頭像 發(fā)表于 05-11 17:54 ?6480次閱讀
    <b class='flag-5'>Linux</b>的<b class='flag-5'>內存</b>管理是什么,<b class='flag-5'>Linux</b>的<b class='flag-5'>內存</b>管理詳解

    如何在Linux設置Git

    Linux設置 Git 十分簡單,但為了獲得完美的配置,我做了以下五件事。
    發(fā)表于 10-21 09:06 ?1267次閱讀

    走進Linux內存系統(tǒng)探尋內存管理的機制和奧秘

    Linux 內存是后臺開發(fā)人員,需要深入了解的計算機資源。合理的使用內存,有助于提升機器的性能和穩(wěn)定性。本文主要介紹Linux 內存組織結構
    的頭像 發(fā)表于 01-05 09:47 ?1926次閱讀

    請問如何在Linux Device Tree中配置預留內存?

    請問如何在Linux Device Tree中配置預留內存
    發(fā)表于 12-29 06:22

    MCUXpresso如何根據“構建配置設置不同的內存配置?

    我將 MCUXpresso v11.6 與 MKL33Z256 一起使用。 我有兩個“構建??配置”:- 調試-發(fā)布(=調試但代碼優(yōu)化) 我還會修改調試和發(fā)布配置之間的內存映射。因為 Debug
    發(fā)表于 03-29 06:47

    linux內存管理機制淺析

    本內容介紹了arm linux內存管理機制,詳細說明了linux內核內存管理,linux虛擬內存
    發(fā)表于 12-19 14:09 ?73次下載
    <b class='flag-5'>linux</b><b class='flag-5'>內存</b>管理機制淺析

    Linux主機IP配置

    Linux如何進行靜態(tài)IP的設置,在主機下運行IP配置的指令
    發(fā)表于 06-03 14:30 ?0次下載

    linux內存管理

    linux內存管理
    發(fā)表于 10-24 11:12 ?3次下載
    <b class='flag-5'>linux</b><b class='flag-5'>內存</b>管理

    如何設置電腦的虛擬內存

    隨著現在電腦的流行,各種品牌的電腦已經非常普遍了,而且配置越來越高,內存也越來越大,同時虛擬內存的擴展也增大了,那么虛擬內存怎么設置最好?下
    發(fā)表于 05-27 17:34 ?2577次閱讀

    Linux系統(tǒng)的共享內存的使用

    但有時候為了讓不同進程之間進行通信,需要讓不同進程共享相同的物理內存,Linux通過 共享內存 來實現這個功能。下面先來介紹一下Linux系統(tǒng)的共享
    的頭像 發(fā)表于 11-14 11:55 ?1558次閱讀

    Linux 內存管理總結

    一、Linux內存管理概述 Linux內存管理是指對系統(tǒng)內存的分配、釋放、映射、管理、交換、壓縮等一系列操作的管理。在
    的頭像 發(fā)表于 11-10 14:58 ?773次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>內存</b>管理總結

    linux查看服務器配置

    Linux操作系統(tǒng)中,了解服務器配置對于系統(tǒng)管理員和網絡工程師而言至關重要。通過查看服務器配置,您可以了解服務器的硬件和軟件組成部分,包括CPU、內存、硬盤、網絡
    的頭像 發(fā)表于 11-17 09:41 ?1495次閱讀

    linux手動設置網絡參數

    Linux 是一種廣泛使用的操作系統(tǒng),提供了豐富的網絡配置選項,允許用戶手動設置網絡參數,以滿足各種網絡需求。本文將詳盡、詳實、細致地介紹 Linux 中手動
    的頭像 發(fā)表于 11-27 15:20 ?1070次閱讀

    Linux環(huán)境變量配置方法

    Linux上環(huán)境變量配置分為設置永久變量和臨時變量兩種。環(huán)境變量設置方法同時要考慮環(huán)境Shell類型,不同類型的SHELL設置臨時變量方法和
    的頭像 發(fā)表于 10-23 13:39 ?634次閱讀

    Linux網絡設置與基礎服務

    Linux網絡設置與基礎服務
    的頭像 發(fā)表于 04-09 11:51 ?2406次閱讀
    <b class='flag-5'>Linux</b>網絡<b class='flag-5'>設置</b>與基礎服務