스왑(실제로는 zram)을 사용하여 Linux 시스템에서 프로세스를 종료하고 싶다고 가정해 보겠습니다. 스왑은 RAM 크기의 절반입니다. RAM의 여유 공간은 10%에 불과하며 스왑 공간도 거의 가득 찼습니다.
이 프로세스는 RAM의 2%만을 사용하고 있지만 스왑의 약 90%를 사용하고 있습니다.
소프트 닫기(SIGTERM)를 수행하고 프로세스가 신호를 포착하고 스스로 닫도록 허용하면 스왑된 모든 매핑이 스왑 해제되지만 전체 프로세스에 맞는 여유 RAM이 충분하지 않습니다.
따라서 SIGKILL을 사용하여 프로세스를 종료하는 것이 더 나을 수 있지만 OOM-killer가 다른 프로세스나 전체 X 세션을 종료하거나 메모리 부족으로 인해 초기화될까 봐 여전히 걱정됩니다.
그렇다면 종료 신호를 보내면 커널이 프로세스의 스왑된 부분을 물리적 메모리로 이동하게 됩니까?(나는 무엇을 기대해야 합니까? 커널 버전에 따라 달라지나요?)
그렇다면, 그러한 경우에는 어떻게 해야 합니까? 목표는 나머지 프로세스를 건드리지 않고 프로세스를 종료하는 것입니다(다른 중요한 프로세스가 실행 중임).
게다가 하나의 프로세스가 아니라 프로세스의 트리이고 애플리케이션이 자체적으로 종료되도록 할 수 없는 경우 이를 올바르게 종료하는 방법은 무엇입니까?
답변1
일반적으로 페이지는 필요하지 않은 한 RAM으로 다시 스왑되지 않습니다. 즉, 페이지가 실제로 무언가에 의해 액세스되는 경우에만 페이지가 RAM으로 다시 로드됩니다(액세스 스레드가 계속되도록 허용하기 전에 OS가 페이지를 RAM으로 다시 로드하여 처리하는 MMU에서 페이지 오류 예외가 발생함). 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)