스왑(실제로는 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)