如何理解Linux中的OOM Out Of Memory Killer 機制?

時間 2021-12-27 13:29:45

1樓:最難不過二叉樹

針對題主的疑惑嘗試回答下:

當物理記憶體不夠的時候啟用虛擬記憶體不就行了嗎? 一般系統管理員會設定swap,記憶體不夠時會把暫時不用的記憶體頁swap到磁碟,騰出空間,也就是你說的虛擬記憶體了。但是這個swap大小都會設定為某乙個值,所以記憶體+swap 也會面臨都耗盡的情況。

為什麼不可以當乙個程式試圖malloc記憶體的時候簡單地返回錯誤? 考慮這種情景:A程序瘋狂分配記憶體,導致系統可用的記憶體已用完,此時B程序需要分配記憶體空間,那B程序肯定分配空間失敗啊,不斷丟擲異常,掛掉的還是無辜的B;如果是OS自己需要分配記憶體空間,發現malloc返回失敗,那就嚴重多了,為了不影響後面的邏輯,OS會更傾向於與fast fail,選擇shutdown。

所以作業系統層面的OOM Killer機制還是挺有用的,系統向使用者提供了可以保護程序免殺的手段:直接修改/proc//oom_score_adj檔案,將其置為-1000。

以前是通過/proc//oom_score來控制的,但近年來新版linux已經使用oom_score_adj來代替舊版的oom_score,可以參考:https://

2樓:呵呵一笑百媚生

關於OOM最近我有深刻體會。

我的linux機器記憶體16G,硬碟SSD,上次自己編譯強行跑了乙個開源軟體。結果沒過一會兒,我突然滑鼠鍵盤完全失去響應,圖形桌面凍住不動……自然是因為程式發瘋耗盡我的記憶體,然後瘋狂磁碟交換,不知道OOM Killler為什麼沒有干預。如果不是ssh連上去還能一幀一幀的操作,我恐怕只能強摁電源重啟了。

記憶體壓力過高時拒絕給執行中的應用程式分配記憶體,那就相當於把釋放記憶體壓力的任務交給了乙個很可能已經發瘋了的應用程式程序……這樣的作業系統能指望有多穩定健壯?單程序fast failed總比重啟整個系統損失小。

關於malloc,它分配的應該是虛擬記憶體。應用程式申請大量的虛擬記憶體並不會立即占用大量系統物理記憶體。而物理記憶體飆高的時候,並不是因為程式在大量malloc,而是程式真的在大範圍訪問已分配的到的虛擬位址空間。

如果讓malloc在虛擬記憶體用盡時報錯,首先那不太現實,因為虛擬位址空間太大了,其次這也沒啥意義,因為虛擬記憶體快用盡時可能物理記憶體並不占用多少,對系統沒啥影響。

如果讓malloc在物理記憶體快用盡時報錯,那……那要這虛擬記憶體機制有何用?

3樓:維吉特伯

剛好最近遇到了幾次OOM的問題。

Linux的OOM機制的存在跟它的overcommit特性有關。

所謂overcommit就是作業系統分配給程序的總記憶體大小超過了實際可用的記憶體,這樣做的原因是程序實際上使用的記憶體往往比申請的記憶體要少。比如有個程序申請了1G的記憶體,但實際上它只在一小段時間裡載入了大量資料,需要使用較大的記憶體,而在執行過程的其他大部分時間裡只用了100M的記憶體。這樣其實有900多M的內存在大部分時間裡是閒置的,完全可以分給其他程序,overcommit的機制就能充分利用這些閒置的記憶體。

Unix/Linux的記憶體分配策略是lazy的,申請的時候不會分配物理記憶體,只有在使用的時候才分配,為了盡可能地提高記憶體地利用效率,系統大部分情況下都會「答應」申請記憶體的要求。因為overcommit的存在,系統沒辦法在程序執行的時候就預判記憶體是否會耗盡,只有在真正分配記憶體的時候才會發覺:誒,記憶體不夠了?

這時候為了防止系統崩潰,只好用OOM killer犧牲掉乙個或者幾個程序了。相比系統崩潰,這種做法更可以接受一點。

個人理解OOM和overcommit算是一種trade-off,這種機制讓系統盡可能地利用了物理記憶體,代價就是在某些情況下需要犧牲一些「無辜」的程序。在大部分情況下這種機制還是挺好用的,只要物理記憶體沒被耗光就不會有什麼問題。

4樓:

首先應該了解到,所有程序都是在虛擬記憶體上的,使用越頻繁,該部分在物理記憶體就越久。

核心的記憶體有幾種特點:

a. 通過虛存引用的都是可以移動的

b. 可重建的內容無需換出

c. 快取可以直接被覆蓋

記憶體處理也就針對這些特點來做,但是就算是這樣,物理記憶體依然還是會被填滿,此時為了保證系統的正常執行必須騰出一些物理記憶體出來,騰出物理記憶體的原因大概有以下兩個:

a. 核心需要一段連續物理記憶體,各種方法都找不到這樣的記憶體

b. 真到了山窮水盡的地步,完全沒記憶體了,比如嵌入式系統

那此時就會檢查系統上的程序,但是核心好像會評估效益,即殺死程序之後是否真能騰出來這麼多記憶體。

在下之前對此有做過實驗,在2G記憶體的系統上用malloc分配3.5G記憶體之後sleep,根本不會出任何問題,但是malloc緊接著memset,可以看到隨著時間往前走,swap逐步被填滿,接著是物理記憶體,直到剩下幾十M的時候被kill掉。

這個思路同時可以向另外乙個方向走,即假設先前乙個程序佔了1.8G記憶體之後sleep,然後後面乙個程序又試圖分配500M,如果此時哪個1.8G的程序大部分記憶體都已經進到swap,而此時500M的記憶體則大部分都在物理記憶體中,那可以看下兩種抉擇:

a. 殺掉1.8G(無辜的)的意味著騰出了部分磁碟,然後還要進一步換出記憶體才能達到目標,這段時間也許又有程序占用大量記憶體

b. 直接殺掉當前500M(犯事的)的則立刻可以使用數量相當的記憶體

作為核心設計者,那種會好一些呢?

5樓:王coder

虛擬記憶體在使用的時候最終要落實到物理記憶體,如果物理記憶體只有1G swap 1G 總共2G空間可以用。目前已經使用了1.8G 若有程式現在申請1G,malloc申請可以成功,因為小於虛擬位址空間。

但是使用的時候,比如要寫資料到這塊空間,發現這塊空間對應不到物理空間(物理1G記憶體用完,想要將不用的物理記憶體資料交換出去吧,發現交換分割槽已經全用完了) 這時該怎麼辦?

個人理解,不一定對

6樓:

首先解釋兩個概念:

swap:在linux裡面,當物理記憶體不夠用了,而又有新的程式請求分配記憶體,那麼linux就會選擇將其他程式暫時不用的資料交換到物理磁碟上(swap out),等程式要用的時候再讀進來(swap in)。這樣做的壞處顯而易見,swap in/swap out這裡的代價比較大,相比資料一直放在記憶體裡面,多了讀磁碟的操作,而磁碟IO代價。。

大家都懂的。

OOM:out of memory,指在linux裡面,由於系統記憶體壓力,系統會選擇保護一些系統程序,而將一些其他的程序kill掉,釋放記憶體。

怎麼避免程序因為OOM機制被kill掉?

1. 與OOM相關的幾個檔案是 /proc//oom_adj 、 /proc//oom_score。前者是乙個權值-16至15,預設是0,設定為-17表示永遠不被kill,其餘情況值越大越容易被kill。

後者就是它計算出來的乙個值,就是根據這個值來選擇哪些程序被kill掉的。

2. 上面放置使用swap中的第三個方法 overcommit引數,因為它分配不出記憶體就會返回錯誤,所以永遠也不能達到記憶體被耗盡。OOM也就不會有影響了。

3 至於Liunx為什麼要這麼做,鬼知道!反正Android也這麼幹!

Linux中,應該如何正確理解使用正規表示式的點符號?

劉長元 你的問題包含2部分,一是grep是如何運作的,二是你對於正規表示式理解問題。grep grep的工作模式是,讀取給定的檔案或是STDIN 以行為單位,去做匹配,根據你給定的正規表示式來看是否匹配成功。如果成功,預設情況下會輸出到STDOUT。所以,對於你的情況來說,輸出非空行的內容,就代表你...

linux中沒有了像windows中的碟符,那怎樣開啟磁碟呢?

Jack Yan windows裡面的磁碟分割槽直接就是c盤d盤e盤,然後檔案和目錄就在這些盤裡面。而linux是先有乙個邏輯的目錄結構樹,起點是 只有這個根分割槽掛在在了乙個磁碟分割槽上面,那麼這個根目錄下的所有檔案和目錄就都在這個分割槽上面,如果有多個磁碟分割槽,是不是就把多個根分割槽掛載在多個...

如何理解卷積,另外如何理解影象處理中的卷積?

烈日烤魚 影象上的卷積其實是乙個很簡單和傻瓜的概念,千萬別被名字嚇到了.影象是二維陣列 方便起見,用一維陣列舉例.卷積1 2 3 4 5 和 10 20 30它的結果也是乙個陣列.這個陣列第乙個值就是 1 10 2 10 3 30 其實就是對應項相乘,求和.第二個值就是 2 10 3 20 4 30...