向交換的程序發送 SIGKILL 是否會在終止之前取消交換?

向交換的程序發送 SIGKILL 是否會在終止之前取消交換?

假設我想用swap(實際上是zram)終止Linux機器上的一個進程。交換區大小是 RAM 的一半。 RAM 中只有 10% 的可用空間,而且交換區也幾乎已滿。

該進程僅使用 2% 的 RAM,但使用了大約 90% 的交換空間。

執行軟體關閉 (SIGTERM) 並允許進程捕獲訊號並自行關閉將導致取消交換所有交換的映射,但沒有足夠的可用 RAM 來容納整個進程。

因此,使用 SIGKILL 終止進程可能會更好,但我仍然擔心 OOM-killer 會因為記憶體不足而終止其他進程,甚至整個 X 會話或 init。

那麼發送終止訊號是否會使核心將進程的交換部分移到物理記憶體中?我該期待什麼?它取決於核心的版本嗎?

如果是的話,這種情況該怎麼辦?目標是終止進程而不觸及其餘進程(還有其他重要進程正在運行)。

此外,當它不是一個進程而是一棵進程樹並且我不能讓應用程式自行終止時,如何正確殺死它?

答案1

一般來說,除非需要,否則頁面不會被交換回 RAM。也就是說,只有當頁面實際被某些東西訪問時,該頁面才會被加載回RAM(在MMU 中導致頁面錯誤異常,操作系統將通過在允許訪問線程繼續之前將頁面加載回RAM 來處理該異常)。硬終止進程(使用 SIGKILL)不會運行該進程的任何線程,因此終止的進程無法嘗試存取其任何頁面,並且這些頁面不應載入到 RAM 中。

事實上,即使您不終止該進程並且它恢復運行,它仍然只會將其實際訪問的頁面換入(到 RAM)。此外,如果所有 RAM 已滿並且需要存取不在 RAM 中的另一個頁面,作業系統將選擇 RAM 的其他頁面進行換出(到磁碟),以便在 RAM 中為程式需要存取的頁面騰出空間。只要磁碟上的交換分割區中有一些空間,這種頁面交換就可以無限期地繼續,使所有內容保持活動狀態,而不會觸發 OOM 殺手。當然,如果這種情況經常發生,它確實會減慢你的機器速度,因為它大部分時間都在 RAM 和磁碟之間移動內存,而不是執行程式指令。這稱為“毆打”。

答案2

關於殺死整個進程樹,您可以嘗試以下操作:

# in pid is saved pid of the parent process
CPIDS=`pgrep -P $pid` # gets pids of child processes
for cpid in $CPIDS ; do kill -9 $cpid ; done # first kill children
kill -9 $pid # then the parent (yeah, that sound kinda bad)

相關內容