Linux マシンで swap (実際は zram) を使用してプロセスを終了したいとします。swap は RAM のサイズの半分です。RAM の空き領域は 10% しかなく、swap もほぼいっぱいです。
このプロセスは RAM の 2% のみを使用していますが、スワップは約 90% を使用しています。
ソフトクローズ (SIGTERM) を実行し、プロセスがシグナルをキャッチして自動的に閉じることを許可すると、スワップされたマッピングがすべてスワップ解除されますが、プロセス全体を収容するのに十分な空き RAM がありません。
そのため、SIGKILL を使用してプロセスを強制終了する方がよいかもしれませんが、メモリ不足により OOM-killer が他のプロセスや X セッション全体、または init を強制終了してしまうのではないかと心配しています。
では、kill シグナルを送信すると、カーネルはプロセスのスワップされた部分を物理メモリに移動するのでしょうか?(何を期待すればよいでしょうか? カーネルのバージョンによって異なりますか?)
もしそうなら、そのような場合にはどうすればよいでしょうか? 目標は、残りのプロセスに影響を与えずにプロセスを終了することです (他の重要なプロセスが実行中です)。
さらに、プロセスが 1 つではなくプロセス ツリーであり、アプリケーションを単独で終了できない場合、それを正しく終了するにはどうすればよいでしょうか。
答え1
一般的に、ページは必要でない限り RAM にスワップバックされません。つまり、ページが実際に何かによってアクセスされた場合にのみ、ページは RAM にロードバックされます (MMU でページ フォールト例外が発生しますが、OS はこれを処理して、アクセスしているスレッドを続行する前にページを RAM にロードバックします)。プロセスをハード キル (SIGKILL を使用) すると、プロセスのスレッドは実行されないため、キルされたプロセスはどのページにもアクセスできず、それらのページは RAM にロードされません。
実際、プロセスを強制終了せずに実行を再開した場合でも、実際にアクセスしたページのみが RAM にスワップインされます。さらに、すべての RAM がいっぱいで、RAM にない別のページにアクセスする必要がある場合、OS は 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)