chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

3天內不再提示

OOM Killer機制學習

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 作者:馬哥Linux運維 ? 2022-12-19 16:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

當系統(tǒng)內存不足以分配時,Linux內核會使用一種OOM Killer(Out-Of-Memory Killer)機制釋放內存,該機制通過一系列比較選擇出最適合的進程并將其kill掉,從而達到保障系統(tǒng)穩(wěn)定運行的目的。那么在內核中,OOM Killer具體是怎么運轉的呢?

一、觸發(fā)過程

在申請內存時,必然會調用alloc_page(),在__alloc_pages中有以下調用關系:

17124298-7df8-11ed-8abf-dac502259ad0.png

其中,在__alloc_pages_slowpath中,當反復嘗試reclaim和compact后仍不成功,就會調用__alloc_pages_may_oom進行內存釋放。

/*
*Ifwefailedtomakeanyprogressreclaiming,thenweare
*runningoutofoptionsandhavetoconsidergoingOOM
*/
if(!did_some_progress){
if(oom_gfp_allowed(gfp_mask)){
if(oom_killer_disabled)
gotonopage;
/*Coredumpscanquicklydepleteallmemoryreserves*/
if((current->flags&PF_DUMPCORE)&&
!(gfp_mask&__GFP_NOFAIL))
gotonopage;
page=__alloc_pages_may_oom(gfp_mask,order,
zonelist,high_zoneidx,
nodemask,preferred_zone,
classzone_idx,migratetype);
......
}

如果定義了oom_killer_disabled,就會直接goto到nopage,不會觸發(fā)OOM機制(此值默認為0).

二、工作過程(基于Linux-3.18)

當內核檢測到內存不足,執(zhí)行到out_of_memory時,OOM Killer會選擇一個進程并把他kill掉:

p = select_bad_process(&points, totalpages, mpol_mask, force_kill);

具體的選擇過程在select_bad_process中進行:

/*
*Simpleselectionloop.Wechosetheprocesswiththehighest
*numberof'points'.Returns-1onscanabort.
*
*(notdocbooked,wedon'twantthisoneclutteringupthemanual)
*/
staticstructtask_struct*select_bad_process(unsignedint*ppoints,
unsignedlongtotalpages,constnodemask_t*nodemask,
boolforce_kill)
{
structtask_struct*g,*p;
structtask_struct*chosen=NULL;
unsignedlongchosen_points=0;

rcu_read_lock();
for_each_process_thread(g,p){
unsignedintpoints;

switch(oom_scan_process_thread(p,totalpages,nodemask,
force_kill)){
caseOOM_SCAN_SELECT:
chosen=p;
chosen_points=ULONG_MAX;
/*fallthrough*/
caseOOM_SCAN_CONTINUE:
continue;
caseOOM_SCAN_ABORT:
rcu_read_unlock();
return(structtask_struct*)(-1UL);
caseOOM_SCAN_OK:
break;
};
points=oom_badness(p,NULL,nodemask,totalpages);
if(!points||points

select_bad_process會選擇一個points數(shù)值最高的進程并返回。在宏for_each_process_thread循環(huán)里,通過switch和oom_scan_process_thread對一些進程做特殊化處理,如一些進程不適合被結束,就跳過本次循環(huán)。如果該進程沒有特殊狀態(tài),oom_scan_process_thread返回OOM_SCAN_OK,繼續(xù)向下進行判斷。這里使用了oom_badness對其points值進行計算。

/**
*oom_badness-heuristicfunctiontodeterminewhichcandidatetasktokill
*@p:taskstructofwhichtaskweshouldcalculate
*@totalpages:totalpresentRAMallowedforpageallocation
*
*Theheuristicfordeterminingwhichtasktokillismadetobeassimpleand
*predictableaspossible.Thegoalistoreturnthehighestvalueforthe
*taskconsumingthemostmemorytoavoidsubsequentoomfailures.
*/
unsignedlongoom_badness(structtask_struct*p,structmem_cgroup*memcg,
constnodemask_t*nodemask,unsignedlongtotalpages)
{
longpoints;
longadj;

if(oom_unkillable_task(p,memcg,nodemask))
return0;

p=find_lock_task_mm(p);
if(!p)
return0;

adj=(long)p->signal->oom_score_adj;
if(adj==OOM_SCORE_ADJ_MIN){
task_unlock(p);
return0;
}

/*
*ThebaselineforthebadnessscoreistheproportionofRAMthateach
*task'srss,pagetableandswapspaceuse.
*/
points=get_mm_rss(p->mm)+atomic_long_read(&p->mm->nr_ptes)+
get_mm_counter(p->mm,MM_SWAPENTS);
task_unlock(p);

/*
*Rootprocessesget3%bonus,justlikethe__vm_enough_memory()
*implementationusedbyLSMs.
*/
if(has_capability_noaudit(p,CAP_SYS_ADMIN))
points-=(points*3)/100;

/*Normalizetooom_score_adjunits*/
adj*=totalpages/1000;
points+=adj;

/*
*Neverreturn0foraneligibletaskregardlessoftherootbonusand
*oom_score_adj(oom_score_adjcan'tbeOOM_SCORE_ADJ_MINhere).
*/
returnpoints>0?points:1;
}

在oom_badness的上半部分,對進程做了一些判斷,排除了不可進行kill的進程以及oom_score_adj為OOM_SCORE_ADJ_MIN(-1000)的進程,進行了return 0。接著是進行比重計算,將rss、nr_ptes、swap空間使用量占RAM比重相加。如果是Root進程則去掉3%的比重points -= (points * 3) / 100;。之后對adj進行歸一化并與points相加,在返回值計算時,使用了一個三目運算符,即當points大于0時,返回points,否則返回1。這里注釋給出的原因是,對于有資格的進程(即可以被OOM Killer掉的進程),是絕不能返回0的。(這里我的理解是,如果points返回0,這個進程可能在之后的比較中就處于劣勢,成為漏網之魚)

17269194-7df8-11ed-8abf-dac502259ad0.png

再回到select_bad_process中看,之后跟的一個if比較就是為了進行取最大值的判斷,再之后判斷該進程是否為thread_group_leader,若是則continue跳過本次循環(huán),否則該進程就是被chosen的進程。

再回到out_of_memory中,得到p值后,需要對其進行判斷:

if(!p){
dump_header(NULL,gfp_mask,order,NULL,mpol_mask);
panic("Outofmemoryandnokillableprocesses...
");
}
if(p!=(void*)-1UL){
oom_kill_process(p,gfp_mask,order,points,totalpages,NULL,
nodemask,"Outofmemory");
killed=1;
}

當p是0時,即沒有找到可以kill掉的進程,內核發(fā)出一個panic。當p不是0時,即找到了可以kill掉的進程,則通過oom_kill_process將其kill。

在oom_kill_process中有個“有意思”的事是,在kill之前,會先遍歷其子進程,重新通過oom_badness計算出一個最適合被kill掉的子進程,該子進程會有限考慮被kill掉,從而避免kill父進程導致的接管子進程的工作開銷。并且最終被kill掉的進程的名字叫victim,這個單詞的中文含義是犧牲者,有點是為了整個系統(tǒng)的穩(wěn)定運轉而犧牲的意思。在這之后OOM Killer會kill掉和victim使用相同虛擬內存的進程,并通過發(fā)送SIGKILL信號將其終止。

1764f574-7df8-11ed-8abf-dac502259ad0.png

三、到底為什么會發(fā)生Out Of Memory?

因為物理內存頁的分配發(fā)生在使用的瞬間而非分配的瞬間。若某個進程申請了200MB內存,但實際上只使用了100MB,未使用到的100MB根本沒有分配物理內存頁。當進程需要內存時,進程從內核得到的只是虛擬地址的使用權,而不是實際的物理地址,實際的物理內存只有當進程真的去訪問新獲取的虛擬地址時,產生缺頁異常,從而進入分配實際物理地址的過程,之后系統(tǒng)返回產生異常的地址,重新執(zhí)行內存訪問。虛擬內存需要物理內存作為支撐,當分配了太多虛擬內存,導致物理內存不夠時,就發(fā)生了Out Of Memory。這種允許超額commit的機制就是overcommit。

overcommit即操作系統(tǒng)在應用申請內存空間時不去檢查是否超出當前可用量,隨意滿足申請要求,應用也不管實際是否有足夠多的內存可使用,認為我申請了2G,OS肯定就給我2G使用。最后,隨著內存越用越多,OS發(fā)現(xiàn)內存不夠用了,必須要收回一些內存才行,就觸發(fā)了上述的OOM Killer機制回收內存。

Linux根據(jù)參數(shù) vm.overcommit_memory設置overcommit:

0 ——默認值,啟發(fā)式overcommit,它允許overcommit,但太明顯的overcommit會被拒絕,比如malloc一次性申請的內存大小就超過了系統(tǒng)總內存。

1 ——Always overcommit. 允許overcommit,對內存申請來者不拒。

2 ——不允許overcommit,提交給系統(tǒng)的總地址空間大小不允許超過CommitLimit。(CommitLimit 就是overcommit的閾值,申請的內存總數(shù)超過CommitLimit的話就算是overcommit)

四、總結

由于物理內存的分配機制,以及overcommit的存在,導致了在物理內存不夠時的OOM Killer。OOM Killer機制很有意思,它為了保護整個系統(tǒng)的安全穩(wěn)定運行,需要找出一個最合適的進程kill掉。這是不得已而為之,內核必須在kill掉進程和系統(tǒng)崩潰之間選擇其中一個。內核代碼中out_of_memory注釋中也體現(xiàn)了這種無奈。> * If we run out of memory, we have the choice between either

killing a random task (bad), letting the system crash (worse)

OR try to be smart about which process to kill. Note that we

don't have to be perfect here, we just have to be good.

在選擇合適的進程時,OOM Killer會挑選一個占用內存最大的進程,這也很好理解,畢竟kill掉一個大的可以獲得更多的物理內存,并且損失也比較小。如果kill掉多個小的,損失會比較大。Linux內核總是去選擇更高效的方法。

審核編輯:湯梓紅

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

    關注

    3

    文章

    1416

    瀏覽量

    41442
  • Linux
    +關注

    關注

    87

    文章

    11511

    瀏覽量

    213823
  • 內存
    +關注

    關注

    8

    文章

    3125

    瀏覽量

    75270

原文標題:OOM Killer機制學習

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    容器JVM內存配置最佳實踐

    Killer機制,此時系統(tǒng)會終止內存占用較多的進程以保證系統(tǒng)的正常運行。特別是在容器環(huán)境下,不合理的JVM堆參數(shù)設置會導致各種異常現(xiàn)象產生,例如應用堆大小還未到達JVM設置的堆閾值或應用的規(guī)格限制,就因為OOM導致重啟等。
    發(fā)表于 06-20 09:45 ?1216次閱讀
    容器JVM內存配置最佳實踐

    ESP8266真的是Arduino Killer

    一大早起來看見篇文章,標題好驚悚[ Meet the Arduino Killer: ESP8266]人家剛要相親相愛,你們標題party就冒出來寫killer這么嚇人的文章,真的好么?
    發(fā)表于 08-20 06:50

    linux內核oom機制分析

    Linux 內核有個機制OOM killer(Out-Of-Memory killer),該機制會監(jiān)控那些占用內存過大,尤其是瞬間很快消耗
    發(fā)表于 11-13 17:01 ?1561次閱讀
    linux內核<b class='flag-5'>oom</b><b class='flag-5'>機制</b>分析

    基于非聯(lián)合型學習機制學習神經元模型

    針對生物神經細胞所具有的非聯(lián)合型學習機制,設計了具有非聯(lián)合型學習機制的新型神經元模型學習神經元。首先,研究了非聯(lián)合型學習機制中習慣化學習機制
    發(fā)表于 11-29 10:52 ?0次下載
    基于非聯(lián)合型<b class='flag-5'>學習機制</b>的<b class='flag-5'>學習</b>神經元模型

    如何制作USB Killer

    注意:使用此USB Killer會損壞您的設備,請自行使用風險。
    的頭像 發(fā)表于 11-15 17:01 ?8273次閱讀

    一個線上服務OOM的問題分享

    大家都知道,如果出現(xiàn)了線上OOM問題,為了不影響用戶的正常使用,最快的解決辦法就是重啟服務。
    的頭像 發(fā)表于 10-24 10:47 ?1239次閱讀

    什么是OOM機制?怎么防止進程因為OOM機制而被殺掉?

    有時候我們會發(fā)現(xiàn)系統(tǒng)中某個進程會突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于 OOM機制 導致進程被殺掉。
    的頭像 發(fā)表于 02-06 11:45 ?3302次閱讀

    細說Linux Out Of Memory機制

    有時候我們會發(fā)現(xiàn)系統(tǒng)中某個進程會突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于 OOM機制 導致進程被殺掉。
    的頭像 發(fā)表于 02-12 09:57 ?1195次閱讀

    一圖解析K8S OOM和CPU節(jié)流

    使用 Kubernetes 時,內存不足 (OOM) 錯誤和 CPU 節(jié)流是云應用程序中資源處理的主要難題。
    的頭像 發(fā)表于 02-15 17:17 ?1695次閱讀

    什么是OOM機制?怎么防止進程因為OOM機制而被殺掉?

    有時候我們會發(fā)現(xiàn)系統(tǒng)中某個進程會突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于 OOM機制 導致進程被殺掉。
    的頭像 發(fā)表于 06-21 08:59 ?9148次閱讀
    什么是<b class='flag-5'>OOM</b><b class='flag-5'>機制</b>?怎么防止進程因為<b class='flag-5'>OOM</b><b class='flag-5'>機制</b>而被殺掉?

    jvm哪些區(qū)域會發(fā)生oom

    of Memory,OOM),本文將詳細介紹 JVM 內容可能發(fā)生 OOM 的區(qū)域。OOM 是指應用程序在申請分配內存時,沒有足夠的內存供其使用,導致程序無法正常執(zhí)行。 堆(Heap)區(qū)域: 堆是 JVM 中最大的一塊內存區(qū)域
    的頭像 發(fā)表于 12-05 11:51 ?1756次閱讀

    Java oom異常的原因分析

    Java中的OOM(Out of Memory)異常是指當程序在運行過程中無法分配足夠的內存空間時拋出的異常。在Java中,內存分為堆內存(Heap)和棧內存(Stack)。堆內存用于存儲對象和數(shù)
    的頭像 發(fā)表于 12-05 13:43 ?1189次閱讀

    oom異常的原因和解決方法

    一、OOM異常的原因 OOM異常的出現(xiàn)通常是由于以下幾個原因造成的: 1.1 內存泄漏 內存泄漏是指資源在使用完畢后沒有被正確釋放或回收,從而導致內存不斷占用的現(xiàn)象。常見的內存泄漏問題包括對象未被
    的頭像 發(fā)表于 12-05 13:45 ?7738次閱讀

    Java怎么排查oom異常

    Java中的OOM(Out of Memory)異常是指當Java虛擬機的堆內存不足以容納新的對象時拋出的異常。OOM異常是一種常見的運行時異常,經常出現(xiàn)在長時間運行的Java應用程序或處理大數(shù)
    的頭像 發(fā)表于 12-05 13:47 ?1624次閱讀

    Java應用OOM問題的排查過程

    導讀 本文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。 前言:此文記錄最近一例Java應用OOM問題的排查過程,希望可以給遇到類似問題的同學提供參考。在本地
    的頭像 發(fā)表于 02-12 11:15 ?656次閱讀
    Java應用<b class='flag-5'>OOM</b>問題的排查過程