【Overcommit和OOM】
?????? ?在Unix中,當一個用戶進程使用malloc()函數(shù)申請內(nèi)存時,假如返回值是NULL,說明當前系統(tǒng)沒有足夠的可用內(nèi)存。一般程序都會判斷malloc返回值是null時便報錯退出。
? ?????因為進程申請內(nèi)存后,可能并不會馬上使用內(nèi)存。所以有時候,為了系統(tǒng)能夠運行更多的程序,它可以對于超出自身剩余內(nèi)存的malloc請求也返回成功。這種行為叫做Overcommit。
? ? ? ?Linux下overcommit有三種策略:
?????? ??0. 啟發(fā)式策略。合理的overcommit會被接受,不合理的overcommit會被拒絕。?
????? ? ?1. 任何overcommit都會被接受。?
????? ? ?2. 當系統(tǒng)分配的內(nèi)存超過swap+N%*物理RAM(N%由vm.overcommit_ratio決定)時,會拒絕commit。?
? ????? Overcommit采用哪種策略可以通過/proc/sys/vm/overcommit_memory設(shè)置(可將該參數(shù)設(shè)置為0/1/2,對應(yīng)上面3中策略)。 ? ? Overcommit的百分比由vm.overcommit_ratio設(shè)置。如:
? ?# echo 2 > /proc/sys/vm/overcommit_memory????
? ?# echo 60 > /proc/sys/vm/overcommit_ratio
【大頁內(nèi)存與快表TLB】
? ?????進程訪問內(nèi)存時,傳遞給CPU的是進程的虛擬內(nèi)存地址,CPU需要將虛擬內(nèi)存轉(zhuǎn)換為物理內(nèi)存地址,再去物理內(nèi)存獲取數(shù)據(jù)。從虛擬內(nèi)存到物理內(nèi)存的映射就依賴頁表。
? ? ? ?頁表是保存在物理內(nèi)存中的一個頁表條目集合。如果要訪問的虛擬內(nèi)存頁之前已經(jīng)映射到了物理內(nèi)存,則該映射關(guān)系會被記錄到頁表中。后續(xù)再訪問該虛擬內(nèi)存地址時,CPU會通過頁表中查找到的映射關(guān)系得到對應(yīng)的物理地址;如果映射關(guān)系不存在,那么就會發(fā)生缺頁中斷,中斷處理程序會完成虛擬內(nèi)存到物理內(nèi)存你的映射,并記錄到頁表中以供后續(xù)查詢。
? ? ? ?但是內(nèi)存的處理速度相比CPU來說還是慢很多。如果CPU每次訪問內(nèi)存都要查詢頁表去獲取映射關(guān)系,那么必然會對性能產(chǎn)生較大的影響。TLB就是為了解決這個問題出現(xiàn)的。
? ?????TLB(Translation Lookaside Buffer),旁路緩沖器,又稱快表。TLB的作用是作為內(nèi)存頁表的緩沖。它是CPU中的一個內(nèi)存管理單元,訪問速度會和CPU處于一個量級,遠高于內(nèi)存。CPU需要獲取內(nèi)存映射時,就會先去訪問TLB,如果TLB中已經(jīng)緩存了所需的地址映射,那么就稱為TLB命中,這樣CPU就可以很快的得到虛擬地址對應(yīng)的物理地址,減少了對實際內(nèi)存頁表的訪問,提高了效率。(實際上TLB后面還有多級的高速緩存,最后才是到實際內(nèi)存)

? ? ? ? ?而由于成本等因素限制,TLB不可能做的很大,一般只能緩存512個頁表項,也就是記錄512個虛擬內(nèi)存頁到物理內(nèi)存頁的映射關(guān)系。一般情況下,操作系統(tǒng)的默認內(nèi)存頁大小為4K。這樣的話,TLB中能緩存的最多也就只有2M的內(nèi)存映射關(guān)系。如果訪問這2M的內(nèi)存,TLB可以命中,那么CPU可以很快的獲取映射關(guān)系;如果訪問這2M以外的內(nèi)存,那么TLB的作用就失去了。為了充分發(fā)揮TLB的作用,就引入了大頁內(nèi)存。
????? ? 大頁內(nèi)存(HugePages)的思想就是通過增大內(nèi)存頁的大小,來增加TLB中緩存的內(nèi)存大小,從而增加TLB命中的概率,提高性能。比如將內(nèi)存頁的大小從4K增大到2M,那么TLB中512個頁表項就能緩存1G內(nèi)存地址空間的映射,這樣相比原來的2M,TLB命中的概率大大增加。
? ??????大頁內(nèi)存可以在/proc/meminfo中查看。
