Exec

Cgroup 記憶體限制和程序清除

  • April 25, 2020

我有以下情況:(以下函式取自python)

我有一個正在執行的程序 A 並設置了 cgroup 記憶體限制。

我使用 os.fork() 從 A 派生一個子程序。我們稱它為 B。然後我執行 os.execvp 在 B 中載入一個 shell 腳本。根據http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/exec.html這個程序在與呼叫者(即B)相同的地址空間中執行。

在 B 中執行的 shell 腳本創建了一個 Java 程序,該程序無限期地以給定的堆大小執行並在 OOM 上自動終止。這是通過將*-XX:OnOutOfMemoryError=‘kill -9 %p’*傳遞給 java 命令來實現的。這將創建另一個程序 C 作為 B 的子程序。

從頂部看,我看到 B 是 A 的孩子,C 是 B 的孩子,正如預期的那樣。

下面是疑惑:

  1. cgroup 限制是否僅適用於 A 或 (A+B) 或 (A+B+C)?
  2. 如果達到記憶體限制,將殺死所有程序:A 還是 (A+B) 還是 (A+B+C)?為什麼?它是使用程序 pid 或應用限制的程序的地址空間來辨識的嗎?
  3. 如果在上述情況下,並非所有程序都被殺死,是否有辦法微調 cgroup 設置以殺死所有子程序,因為在這種情況下我們會留下孤立的程序?

我正在使用 Centos7 作為底層作業系統。

我將解決您的每個問題:

  1. cgroup 適用於 A 和 A 的任何後代。您可以嘗試驗證此行為。考慮:
Create a new memory cgroup
# mkdir /sys/fs/cgroup/memory/example

Note the shell's PID:
# echo $$
679

Put the running shell into the new cgroup
# echo $$ > /sys/fs/cgroup/memory/example/cgroup.procs

Examine what processes are in the cgroup.  Here 679 was the
shell's PID; 723 is the pid of cat
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
723

Start a new shell and note its PID
# bash
# echo $$
726

Examine what processes are in the cgroup.  679 was the original
shell.  726 is the second shell.  731 is cat:
# cat /sys/fs/cgroup/memory/example/cgroup.procs
679
726
731
  1. 根據記憶體 cgroup 文件

當一個 cgroup 超過它的限制時,我們首先嘗試從 cgroup 中回收記憶體,以便為 cgroup 觸及的新頁面騰出空間。如果回收不成功,則會呼叫 OOM 常式來選擇並終止 cgroup 中最龐大的任務。

基於此,它不會殺死 cgroup 中的所有程序;它選擇消耗最多記憶體的那個。

  1. 我看不到一種方法來調整哪個程序被殺死以匹配您在此處詢問的內容。有一種方法可以控制 OOM 殺手;例如,請參閱這篇Linux 每週新聞文章。也就是說,如果其中一個父程序被殺死,它所擁有的任何子程序都會重新成為 PID = 1 的程序的父程序(預設情況下)。

引用自:https://unix.stackexchange.com/questions/554288