在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是OOM機(jī)制?怎么防止進(jìn)程因?yàn)镺OM機(jī)制而被殺掉?

Linux閱碼場(chǎng) ? 來源:Linux內(nèi)核那些事 ? 2023-06-21 08:59 ? 次閱讀

有時(shí)候我們會(huì)發(fā)現(xiàn)系統(tǒng)中某個(gè)進(jìn)程會(huì)突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于OOM機(jī)制導(dǎo)致進(jìn)程被殺掉。

今天我們就來介紹一下什么是OOM機(jī)制以及怎么防止進(jìn)程因?yàn)镺OM機(jī)制而被殺掉。

什么是OOM機(jī)制

OOM是 Out Of Memory 的縮寫,中文意思是內(nèi)存不足。而OOM機(jī)制是指當(dāng)系統(tǒng)內(nèi)存不足時(shí),系統(tǒng)觸發(fā)的應(yīng)急機(jī)制。

當(dāng) Linux 內(nèi)核發(fā)現(xiàn)系統(tǒng)中的物理內(nèi)存不足時(shí),首先會(huì)對(duì)系統(tǒng)中的可回收內(nèi)存進(jìn)行回收,能夠被回收的內(nèi)存有如下:

讀寫文件時(shí)的頁(yè)緩存。

為了性能而延遲釋放的空閑 slab 內(nèi)存頁(yè)。

當(dāng)系統(tǒng)內(nèi)存不足時(shí),內(nèi)核會(huì)優(yōu)先釋放這些內(nèi)存頁(yè)。因?yàn)槭褂眠@些內(nèi)存頁(yè)只是為了提升系統(tǒng)的性能,釋放這些內(nèi)存頁(yè)也不會(huì)影響系統(tǒng)的正常運(yùn)行。

如果釋放上述的內(nèi)存后,還不能解決內(nèi)存不足的情況,那么內(nèi)核會(huì)如何處理呢?答案就是:觸發(fā)OOM killer殺掉系統(tǒng)中占用內(nèi)存最大的進(jìn)程。如下圖所示:

84e31e08-0fc7-11ee-962d-dac502259ad0.png

可以看出,OOM killer 是防止系統(tǒng)崩潰的最后一個(gè)手段,不到迫不得已的情況是不會(huì)觸發(fā)的。

OOM killer 實(shí)現(xiàn)

接下來,我們分析一下內(nèi)核是如何實(shí)現(xiàn) OOM killer 的。

由于在 Linux 系統(tǒng)中,進(jìn)程申請(qǐng)的都是虛擬內(nèi)存地址。所以當(dāng)程序調(diào)用malloc()申請(qǐng)內(nèi)存時(shí),如果虛擬內(nèi)存空間足夠的話,是不會(huì)觸發(fā) OOM 機(jī)制的。

當(dāng)進(jìn)程訪問虛擬內(nèi)存地址時(shí),如果此虛擬內(nèi)存地址還沒有映射到物理內(nèi)存地址的話,那么將會(huì)觸發(fā)缺頁(yè)異常。

在缺頁(yè)異常處理例程中,將會(huì)申請(qǐng)新的物理內(nèi)存頁(yè),并且將進(jìn)程的虛擬內(nèi)存地址映射到剛申請(qǐng)的物理內(nèi)存。

如果在申請(qǐng)物理內(nèi)存時(shí),系統(tǒng)中的物理內(nèi)存不足,那么內(nèi)核將會(huì)回收一些能夠被回收的文件頁(yè)緩存。如果回收完后,物理內(nèi)存還是不足的話,那么將會(huì)觸發(fā)swapping機(jī)制(如果開啟了的話)。

swapping機(jī)制會(huì)將某些進(jìn)程不常用的內(nèi)存頁(yè)寫入到交換區(qū)(硬盤分區(qū)或文件)中,然后釋放掉這些內(nèi)存頁(yè),從而達(dá)到緩解內(nèi)存不足的情況。

如果通過上面的手段還不能解決內(nèi)存不足的情況,那么內(nèi)核將會(huì)調(diào)用pagefault_out_of_memory()函數(shù)來殺掉系統(tǒng)中占用物理內(nèi)存最多的進(jìn)程。

我們來看看pagefault_out_of_memory()函數(shù)的實(shí)現(xiàn):

voidpagefault_out_of_memory(void)
{
...
out_of_memory(NULL,0,0,NULL,false);
...
}

可以看出,pagefault_out_of_memory()函數(shù)最終會(huì)調(diào)用out_of_memory()來殺死系統(tǒng)中占用內(nèi)存最多的進(jìn)程。

我們繼續(xù)來看看out_of_memory()函數(shù)的實(shí)現(xiàn):

voidout_of_memory(structzonelist*zonelist,gfp_tgfp_mask,intorder,
nodemask_t*nodemask,boolforce_kill)
{
...

//1.從系統(tǒng)中選擇一個(gè)最壞(占用內(nèi)存最多)的進(jìn)程
p=select_bad_process(&points,totalpages,mpol_mask,force_kill);
...

//2.如果找到最壞的進(jìn)程,那么調(diào)用oom_kill_process函數(shù)殺掉進(jìn)程
if(p!=(void*)-1UL){
oom_kill_process(p,gfp_mask,order,points,totalpages,NULL,
nodemask,"Outofmemory");
killed=1;
}
...
}

out_of_memory()函數(shù)的邏輯比較簡(jiǎn)單,主要完成兩個(gè)事情:

調(diào)用select_bad_process()函數(shù)從系統(tǒng)中選擇一個(gè)最壞(占用物理內(nèi)存最多)的進(jìn)程。

如果找到最壞的進(jìn)程,那么調(diào)用oom_kill_process()函數(shù)將此進(jìn)程殺掉。

從上面的分析可知,找到最壞的進(jìn)程是 OOM killer 最為重要的事情。

那么我們來看看select_bad_process()函數(shù)是怎樣選擇最壞的進(jìn)程的:

staticstructtask_struct*
select_bad_process(unsignedint*ppoints,unsignedlongtotalpages,
constnodemask_t*nodemask,boolforce_kill)
{
structtask_struct*g,*p;
structtask_struct*chosen=NULL;
unsignedlongchosen_points=0;
...

//1.遍歷系統(tǒng)中所有的進(jìn)程和線程
for_each_process_thread(g,p){
unsignedintpoints;
...

//2.計(jì)算進(jìn)程最壞分?jǐn)?shù)值,選擇分?jǐn)?shù)最大的進(jìn)程作為殺掉的目標(biāo)進(jìn)程
points=oom_badness(p,NULL,nodemask,totalpages);
if(!points||points

select_bad_process()函數(shù)的主要工作如下:

遍歷系統(tǒng)中所有的進(jìn)程和線程,并且調(diào)用oom_badness()函數(shù)計(jì)算進(jìn)程的最壞分?jǐn)?shù)值。

選擇最壞分?jǐn)?shù)值最大的進(jìn)程作為被殺掉的目標(biāo)進(jìn)程。

所以,計(jì)算進(jìn)程的最壞分?jǐn)?shù)值就是 OOM killer 的核心工作。我們接著來看看oom_badness()函數(shù)是怎么計(jì)算進(jìn)程的最壞分?jǐn)?shù)值的:

unsignedlong
oom_badness(structtask_struct*p,structmem_cgroup*memcg,
constnodemask_t*nodemask,unsignedlongtotalpages)
{
longpoints;
longadj;

//1.如果進(jìn)程不能被殺掉(init進(jìn)程和內(nèi)核進(jìn)程是不能被殺的)
if(oom_unkillable_task(p,memcg,nodemask))
return0;
...

//2.我們可以通過/proc/{pid}/oom_score_adj文件來設(shè)置進(jìn)程的被殺建議值,
//這個(gè)值越小,進(jìn)程被殺的機(jī)會(huì)越低。如果設(shè)置為-1000時(shí),進(jìn)程將被禁止殺掉。
adj=(long)p->signal->oom_score_adj;
if(adj==OOM_SCORE_ADJ_MIN){
...
return0;
}

//3.統(tǒng)計(jì)進(jìn)程使用的物理內(nèi)存數(shù)
points=get_mm_rss(p->mm)
+atomic_long_read(&p->mm->nr_ptes)
+get_mm_counter(p->mm,MM_SWAPENTS);
...

//4.加上進(jìn)程被殺建議值,得出最終的分?jǐn)?shù)值
adj*=totalpages/1000;
points+=adj;

returnpoints>0?points:1;
}

oom_badness()函數(shù)主要按照以下步驟來計(jì)算進(jìn)程的最壞分?jǐn)?shù)值:

如果進(jìn)程不能被殺掉(init進(jìn)程和內(nèi)核進(jìn)程是不能被殺的),那么返回分?jǐn)?shù)值為 0。

可以通過/proc/{pid}/oom_score_adj文件來設(shè)置進(jìn)程的 OOM 建議值(取值范圍為 -1000 ~ 1000)。建議值越小,進(jìn)程被殺的機(jī)會(huì)越低。如果將其設(shè)置為 -1000 時(shí),進(jìn)程將被禁止殺掉。

統(tǒng)計(jì)進(jìn)程使用的物理內(nèi)存數(shù),包括實(shí)際使用的物理內(nèi)存、頁(yè)表占用的物理內(nèi)存和 swap 機(jī)制占用的物理內(nèi)存。

最后加上進(jìn)程的 OOM 建議值,得出最終的分?jǐn)?shù)值。

通過oom_badness()函數(shù)計(jì)算出進(jìn)程的最壞分?jǐn)?shù)值后,系統(tǒng)就能從中選擇一個(gè)分?jǐn)?shù)值最大的進(jìn)程殺死,從而解決內(nèi)存不足的情況。

禁止進(jìn)程被 OOM 殺掉

有時(shí)候,我們不希望某些進(jìn)程被 OOM killer 殺掉。例如 MySQL 進(jìn)程如果被 OOM killer 殺掉的話,那么可能導(dǎo)致數(shù)據(jù)丟失的情況。

那么如何防止進(jìn)程被 OOM killer 殺掉呢?從上面的分析可知,在內(nèi)核計(jì)算進(jìn)程最壞分?jǐn)?shù)值時(shí),會(huì)加上進(jìn)程的oom_score_adj(OOM建議值)值。如果將此值設(shè)置為-1000時(shí),那么系統(tǒng)將會(huì)禁止 OOM killer 殺死此進(jìn)程。

例如使用如下命令,將會(huì)禁止殺死 PID 為 2000 的進(jìn)程:

$echo-1000>/proc/2000/oom_score_adj

這樣,我們就能防止一些重要的進(jìn)程被 OOM killer 殺死。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux系統(tǒng)
    +關(guān)注

    關(guān)注

    4

    文章

    601

    瀏覽量

    28177
  • PID控制
    +關(guān)注

    關(guān)注

    10

    文章

    461

    瀏覽量

    40889
  • MYSQL數(shù)據(jù)庫(kù)

    關(guān)注

    0

    文章

    96

    瀏覽量

    9680

原文標(biāo)題:細(xì)說|Linux Out Of Memory機(jī)制

文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    容器JVM內(nèi)存配置最佳實(shí)踐

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

    怎么才能避免SD卡頻繁讀寫防止死機(jī)機(jī)制

    怎么才能避免SD卡頻繁讀寫防止死機(jī)機(jī)制
    發(fā)表于 10-23 08:14

    linux內(nèi)核oom機(jī)制分析

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

    一個(gè)線上服務(wù)OOM的問題分享

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

    OOM Killer機(jī)制學(xué)習(xí)

    當(dāng)系統(tǒng)內(nèi)存不足以分配時(shí),Linux內(nèi)核會(huì)使用一種OOM Killer(Out-Of-Memory Killer)機(jī)制釋放內(nèi)存,該機(jī)制通過一系列比較選擇出最適合的進(jìn)程并將其kill掉,從
    的頭像 發(fā)表于 12-19 16:17 ?1438次閱讀

    什么是OOM機(jī)制?怎么防止進(jìn)程因?yàn)?/b>OOM機(jī)制被殺掉

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

    細(xì)說Linux Out Of Memory機(jī)制

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

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

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

    進(jìn)程間通信的機(jī)制有哪些

    通信比較難,Linux內(nèi)核提供了多種進(jìn)程間通信的機(jī)制。 同一個(gè)進(jìn)程的不同模塊(譬如不同的函數(shù))之間進(jìn)行通信都是很簡(jiǎn)單的,譬如使用全局變量等。 通常情況下,大部分的程序是不要考慮進(jìn)程間通
    的頭像 發(fā)表于 07-21 11:23 ?1171次閱讀
    <b class='flag-5'>進(jìn)程</b>間通信的<b class='flag-5'>機(jī)制</b>有哪些

    OOM會(huì)導(dǎo)致JVM虛擬機(jī)退出嗎

    熟悉Java開發(fā)的人,應(yīng)該會(huì)經(jīng)常遇到的異常:OOM,那么這個(gè)異常會(huì)導(dǎo)致 JVM 虛擬機(jī)退出嗎? 1、結(jié)論 Java虛擬機(jī)(JVM)在運(yùn)行Java應(yīng)用時(shí),可能會(huì)遇到內(nèi)存不足的情況,從而拋出
    的頭像 發(fā)表于 09-30 10:14 ?929次閱讀

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

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

    Java oom異常的原因分析

    據(jù),棧內(nèi)存用于存儲(chǔ)方法調(diào)用和局部變量。 當(dāng)程序需要使用更多內(nèi)存時(shí),會(huì)向操作系統(tǒng)請(qǐng)求更多的內(nèi)存空間。如果操作系統(tǒng)無法分配足夠的內(nèi)存空間,就會(huì)導(dǎo)致OOM異常的發(fā)生。 導(dǎo)致OOM異常的原因有多種,下面將詳細(xì)介紹一些常見的原因。 內(nèi)存
    的頭像 發(fā)表于 12-05 13:43 ?1003次閱讀

    oom異常的原因和解決方法

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

    Java怎么排查oom異常

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

    Java應(yīng)用OOM問題的排查過程

    導(dǎo)讀 本文記錄最近一例Java應(yīng)用OOM問題的排查過程,希望可以給遇到類似問題的同學(xué)提供參考。 前言:此文記錄最近一例Java應(yīng)用OOM問題的排查過程,希望可以給遇到類似問題的同學(xué)提供參考。在本地
    的頭像 發(fā)表于 02-12 11:15 ?462次閱讀
    Java應(yīng)用<b class='flag-5'>OOM</b>問題的排查過程
    主站蜘蛛池模板: 欧美一区二区三区男人的天堂 | 中文字幕一区二区三区免费看 | 亚洲福利一区二区三区 | 欧美精品人爱a欧美精品 | 午夜日本一区二区三区 | 天堂中文www在线 | 免费播放黄色 | 户外露出 自拍系列 | 天天操夜 | 欧美综合一区二区三区 | 天天激情站 | 末成年一级在线看片 | 制服丝袜中文字幕第一页 | 小泽玛利亚在线观看123 | 免费毛片大全 | 免费观看黄a一级视频日本 免费观看黄色网页 | 扒开末成年粉嫩的流白浆视频 | 四虎现在的网址入口 | 日本三级在线视频 | 黄色激情小说视频 | 色网址在线观看 | 亚洲欧美啪啪 | 高清影院在线欧美人色 | yezhulu在线永久网址yellow | 久久夜色tv网站 | 在线国产你懂的 | 欧美一卡二卡科技有限公司 | 成年人午夜影院 | 女主播扒开内衣让粉丝看个够 | 国产亚洲美女精品久久久2020 | 99久久精品费精品国产 | 天天爽天天 | 天天搞天天爽 | 色吧首页dvd | 黄色片日本网站 | 在线观看一区二区三区视频 | 日本free护士姓交 | 欧美成人精品一区二三区在线观看 | 亚洲 欧美 视频 | 欧美人与牲动交xxxx | 欧美天天色 |