五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

一文細說Linux Out Of Memory機制

2023-01-31 17:07 作者:補給站Linux內(nèi)核  | 我要投稿

有時候我們會發(fā)現(xiàn)系統(tǒng)中某個進程會突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于?OOM機制?導致進程被殺掉。

今天我們就來介紹一下什么是?OOM機制?以及怎么防止進程因為?OOM機制?而被殺掉。

什么是OOM機制

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

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

  • 讀寫文件時的頁緩存。

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

當系統(tǒng)內(nèi)存不足時,內(nèi)核會優(yōu)先釋放這些內(nèi)存頁。因為使用這些內(nèi)存頁只是為了提升系統(tǒng)的性能,釋放這些內(nèi)存頁也不會影響系統(tǒng)的正常運行。

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

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


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ? ?


OOM killer 實現(xiàn)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  2. 選擇最壞分數(shù)值最大的進程作為被殺掉的目標進程。

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

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

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

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

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

  4. 最后加上進程的 OOM 建議值,得出最終的分數(shù)值。

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

禁止進程被 OOM 殺掉

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

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

例如使用如下命令,將會禁止殺死 PID 為 2000 的進程:

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


原文作者:Linux內(nèi)核那些事




一文細說Linux Out Of Memory機制的評論 (共 條)

分享到微博請遵守國家法律
东乡族自治县| 苍山县| 长泰县| 永德县| 闻喜县| 满城县| 贺兰县| 习水县| 裕民县| 溆浦县| 南靖县| 阿尔山市| 绵阳市| 泾源县| 浦东新区| 澎湖县| 惠来县| 石屏县| 西宁市| 昌黎县| 泸州市| 蒙山县| 石棉县| 自治县| 武胜县| 晴隆县| 峨眉山市| 千阳县| 临江市| 通江县| 英山县| 宁津县| 绍兴市| 正安县| 眉山市| 许昌县| 赣榆县| 普宁市| 东乡县| 柳州市| 广昌县|