當進程發現沒有記憶體可用時如何處理這種情況?

當進程發現沒有記憶體可用時如何處理這種情況?

當特定進程發現沒有記憶體可用時會發生什麼?

該進程會殺死/重新啟動另一個進程來繼續他們的任務嗎?

或者在這種情況下(需要更多記憶體的進程)會做什麼?

如果可能的話,任何人都可以提供與此相關的良好連結嗎?

答案1

在某些請求分頁虛擬記憶體系統上,作業系統拒絕分配匿名頁面(即包含沒有檔案系統來源的資料的頁面,例如運行時資料、程式堆疊等),除非有足夠的交換空間來交換這些頁面以便釋放實體記憶體。這種嚴格計算的優點是可以保證每個進程訪問它們分配的盡可能多的虛擬內存,但這也意味著可用的虛擬內存量本質上受到交換空間大小的限制。

Linux 核心中的記憶體統計嘗試透過追蹤進程實際使用的記憶體量來補償那些傾向於分配比其使用更多記憶體的程序,並且過度承諾虛擬記憶體量。換句話說,核心分配的虛擬記憶體量可能超過系統上實體記憶體和交換空間的總和。實際上,這意味著記憶體分配malloc()永遠不會失敗。雖然這可以更好地利用實體記憶體和交換空間,但缺點是當使用的記憶體量超過可用的實體記憶體和交換空間量時,核心必須以某種方式釋放記憶體資源以滿足記憶體分配承諾。

用於回收記憶體以填充複用的核心機制稱為記憶體不足殺手(OOM 殺手)。通常,該機制將開始殺死佔用記憶體的「流氓」進程,為其他進程釋放記憶體。 OOM-killer 和記憶體核算演算法的行為可以透過sysctl設定或/proc/sys/vm。如果vm.panic_on_oom設定非零,當系統記憶體不足時,核心將出現恐慌。

OOM-killer 使用的啟發式可以透過vm.oom_kill_allocating_task設定進行修改。預設情況下,OOM-killer 將掃描任務清單並選擇一個佔用大量記憶體的惡意任務來殺死。 OOM-killer 也可以設定為終止觸發記憶體不足情況的任務。

可以透過設定來調整內核記憶體統計演算法vm.overcommit_memory。預設是在過度使用之前執行一些弱啟發式檢查,但記憶體計費演算法也可以設定為嚴格模式,其中虛擬位址空間限制由vm.overcommit_ratio根據以下公式設定的值決定:

    virtual memory = (swap + physical memory * (overcommit_ratio / 100))

當使用嚴格的記憶體統計時,核心將不再分配匿名頁面,除非它有足夠的可用實體記憶體或交換空間來儲存頁面。這意味著該系統必須配置了足夠的交換空間。除非有足夠的實體記憶體或交換空間來滿足記憶體承諾,否則呼叫可能malloc()會失敗。在這些情況下,由程序本身決定適當的行動方案。有些人可能會放棄並徹底失敗,但他們也可能會退回到速度較慢但記憶體效率更高的演算法來執行他們需要記憶體分配的操作。

答案2

這取決於程式配置的用途。簡單的程式只是列印一條錯誤訊息,然後在無法分配足夠的記憶體時終止。有些程式會嘗試自行釋放一些記憶體並重試。有些程序在退出前會執行一些緊急狀態保存。有些程式會以某種方式繼續運行,並且在沒有額外記憶體的情況下繼續運行,也許是在通知用戶某些命令無法執行之後。

雖然原則上一個進程可以殺死另一個進程,但這將是一種極其奇怪的行為。該進程無法知道要殺死哪些進程,也無法保證它能夠取得它們的記憶體。

如果核心偵測到記憶體不足核心可能會基於複雜的啟發法(例如“不殺死sshd”)而不是由應用程式殺死某些進程。

相關內容