スワップ(実際にはzram)を使ってLinuxシステムでプロセスを終了したいとしましょう。スワップ領域はRAMサイズの半分です。 RAMの空き容量は10%にすぎず、スワップ領域はほとんどいっぱいです。
このプロセスはRAMの2%しか使用しませんが、スワップスペースの約90%を使用します。
ソフトシャットダウン(SIGTERM)を実行し、プロセスが信号をキャッチしてそれ自体でシャットダウンすることを許可すると、スワップされたすべてのマッピングはスワップ解除されますが、プロセス全体を受け入れるのに十分な空きRAMがありません。
したがって、SIGKILLを使用してプロセスを終了する方が良いかもしれませんが、メモリ不足のためにOOM-killerが他のプロセスやXセッション全体または初期化を終了することはまだ心配です。
もしそうなら、終了信号を送ると、カーネルはプロセスのスワップされた部分を物理メモリに移動しますか?(私は何を期待すべきですか?カーネルのバージョンによって異なりますか?)
それでは、この場合どうすればよいですか?目標は、残りのプロセスに触れることなくプロセスを終了することです(他の重要なプロセスが実行中です)。
また、プロセスではなくプロセスツリーであり、アプリケーションを自分で終了させることができない場合は、それを正しく終了するにはどうすればよいですか?
答え1
通常、ページは必要ない限りRAMに再スワップされません。つまり、ページは実際に何かによってアクセスされている場合にのみRAMに再ロードされます(MMUはページエラー例外をスローし、アクセススレッドが続行できるようにする前にOSはページを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)