과도한 메모리 할당으로 인해 스 래싱을 일으키는 프로세스를 신속하게 중지하려면 어떻게해야합니까?


19

우리는 모두 그것을 경험했습니다. 일부 프로그램은 엄청난 양의 메모리가 필요한 작업을 수행하도록 요청되었습니다. 이 모든 메모리를 정중하게 할당하려고 시도하면 시스템은 즉시 스 래싱을 시작하고 끝없이 교환되며 느리거나 응답하지 않습니다.

나는 최근에 엄청나게 큰 행렬을 할당하려고하는 Matlab 스크립트로 인해 Ubuntu 랩톱에서 이것을 경험했습니다. ~ 5 분 이상의 스 래싱 후, 콘솔에서 Ctrl-F1을 눌러 Matlab을 죽일 수있었습니다. 차라리 시스템을 즉시 제어하고 문제가되는 프로세스를 중단시킬 수있는 단축 키가 많이 필요합니다. 또는 아마도 그러한 큰 버퍼 할당을 조용히 거부 할 수도 있습니다.

  1. 과도한 스와핑으로 인해 응답하지 않거나 매우 느린 Linux 시스템을 다시 제어 할 수있는 가장 빠른 방법은 무엇입니까?

  2. 예를 들어 프로세스가 할당을 시도 할 수있는 메모리 양을 제한하여 이러한 스와핑을 방지 할 수있는 효과적인 방법이 있습니까?

답변:


12

가장 많은 메모리를 사용하여 프로세스를 종료하려면 Alt-SysRq-F 를 누르 십시오.

  • SysRq 키는 일반적으로 인쇄 키에 매핑됩니다.
  • 그래픽 데스크탑을 사용하는 경우 Alt-SysRq를 누르면 다른 조치 (예 : 스냅 샷 프로그램)가 트리거 되는 경우 Ctrl-Alt-SysRq-F 를 눌러야 할 수도 있습니다 .
  • 랩톱을 사용하는 경우 기능 키도 눌러야합니다.
  • 자세한 내용은 Wikipedia 기사를 참조하십시오 .

5

이 목적을 위해 스크립트를 만들었습니다-https: //github.com/tobixen/thrash-protect

이 스크립트를 프로덕션 서버, 워크 스테이션 및 랩톱에서 성공적으로 실행했습니다. 이 스크립트는 프로세스를 죽이지 않지만 일시적으로 중단합니다. 나중에이 간단한 스크립트가 아닌 경우 스 래싱으로 인해 제어력을 잃어 버린 몇 가지 상황이 있습니다. "최악의"경우에는 위반 프로세스가 많이 느려지고 결국 커널 (OOM)에 의해 종료됩니다. "최상의"경우에는 위반 프로세스가 실제로 완료됩니다. 상황을 쉽게 조사 할 수 있도록 상대적으로 반응을 유지합니다.

물론 "더 많은 메모리를 구입"또는 "스왑을 사용하지 마십시오"는 "스 래싱을 피하는 방법?"이라는 질문에 대한 두 가지 대안적이고 전통적인 답변이지만 일반적으로 제대로 작동하지 않는 경향이 있습니다 (더 많은 메모리를 설치하면 사소한 것이 아니라, 불량 프로세스는 설치된 메모리의 양에 관계없이 모든 메모리를 소모 할 수 있으며, 버퍼링 / 캐싱을위한 메모리가 충분하지 않을 때 스왑 없이도 스 래싱 문제를 일으킬 수 있습니다). 스 래시 방지와 많은 스왑 공간을 권장합니다.


unix.stackexchange.com/a/24646/9108 에 따르면 스왑 비활성화에 대해서는 최상의 옵션이 아닐 수 있습니다.
sashoalm

실제로 누군가 나에게 똑같은 주석을 달았으므로 그 시점에서 쓰 래시 방지 문서를 수정했습니다.
tobixen

4
  1. 과도한 스와핑으로 인해 응답하지 않거나 매우 느린 Linux 시스템을 다시 제어 할 수있는 가장 빠른 방법은 무엇입니까?

이미 Alt-SysRq-F로 답변했습니다

  1. 예를 들어 프로세스가 할당을 시도 할 수있는 메모리 양을 제한하여 이러한 스와핑을 방지 할 수있는 효과적인 방법이 있습니까?

나는이 두 번째 부분에 대답하고 있습니다. 예, ulimit여전히 단일 프로세스를 제한하기에 충분합니다. 당신은 할 수 있습니다 :

  • 통제 불능 상태 인 프로세스에 대한 소프트 한계 설정
  • 추가 보험을 원할 경우 모든 프로세스에 대한 제한을 설정하십시오

또한 간단히 언급했듯이 :

CGroup을 사용하여 리소스 사용을 제한하고 이러한 문제를 방지 할 수 있습니다.

실제로 cgroup은 고급 제어 기능을 제공하지만 현재는 구성하기가 더 복잡합니다.

올드 스쿨 ulimit

일단 떨어져

간단한 예를 들면 다음과 같습니다.

$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)

그것:

  • 전체 메모리 사용의 소프트 제한을 1GB로 설정합니다 (ulimit는 kB 단위로 제한을 가정 함)
  • r2(){ r2 $@$@;};r2 r2스택 메모리를 요청하는 동안 무한히 자신을 두 배로 늘려 CPU와 RAM을 기하 급수적으로 증가 시키는 재귀 bash 함수 호출 을 실행합니다 .

보시다시피 1GB 이상을 요청할 때 중지되었습니다.

참고 -v(즉, 실제 + 스왑 총) 가상 메모리 할당을 운영하고 있습니다.

영구적 인 보호

가상 메모리 할당을 제한 as하는 것은 -vfor 와 같습니다 limits.conf.

단일 오작동 프로세스로부터 보호하기 위해 다음을 수행합니다.

  • 모든 프로세스에 대해 하드 주소 공간 제한을 설정하십시오.
  • address space limit = <physical memory> - 256MB.
  • 따라서 욕심 많은 메모리 사용이나 활성 루프 및 메모리 누수를 가진 단일 프로세스는 모든 실제 메모리를 소비 할 수 없습니다.
  • 256MB 헤드 룸은 ssh 또는 콘솔을 사용한 필수 처리를위한 것입니다.

짧막 한 농담:

$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"

이를 확인하기 위해 다음과 같은 결과가 발생합니다 (예 : 16GB 시스템).

$ cat /etc/security/limits.d/mem.conf
*   hard    as      16135196
$ ulimit -H -v
161351960

노트:

  • 메모리를 사용하여 단일 프로세스에 대해서만 완화합니다.
  • 메모리 부족으로 인해 스 래싱을 유발하는 다중 프로세스 워크로드를 방지하지 않습니다 (cgroup이 그 해답입니다).
  • rsslimits.conf에서 옵션을 사용하지 마십시오 . 최신 커널에서는 존중하지 않습니다.
  • 보수적이다.
    • 이론적으로 프로세스는 많은 양의 메모리를 추측 적으로 요청할 수 있지만 서브 세트 (작은 작업 세트 / 상주 메모리 사용) 만 적극적으로 사용합니다.
    • 위의 하드 제한으로 인해 그러한 프로세스가 중단 될 수 있습니다 (리눅스가 가상 메모리 주소 공간을 초과 커밋 할 수있는 경우에는 프로세스가 제대로 실행 되더라도).

최신 C 그룹

더 많은 제어 기능을 제공하지만 현재 사용하기가 더 복잡합니다.

  • ulimit 오퍼링을 향상시킵니다.
    • memory.max_usage_in_bytes 물리적 메모리를 개별적으로 설명하고 제한 할 수 있습니다.
    • 반면 ulimit -m및 / 또는 rss에서 limits.conf유사한 기능을 제공하는 것을 의미하지만 커널 리눅스 2.4.30 이후 일을하지 않는 한!
  • bootloader에서 일부 커널 cgroup 플래그를 활성화해야합니다 cgroup_enable=memory swapaccount=1.
    • 우분투 16.04에서는 기본적으로 발생하지 않았습니다.
    • 추가 회계 오버 헤드의 일부 성능 영향 때문일 수 있습니다.
  • cgroup / systemd 제품은 비교적 새롭고 공정한 비트를 변경하기 때문에 플럭스 업스트림은 Linux 배포판 공급 업체가 아직 사용하기 쉽지 않은 것을 의미합니다. 14.04LTS와 16.04LTS 사이에서 cgroup을 사용하는 사용자 공간 도구가 변경되었습니다.
    • cgm 이제 공식적으로 지원되는 사용자 공간 도구 인 것 같습니다.
    • 시스템 단위 파일은 아직 ssh와 같은 중요한 서비스의 우선 순위를 지정하기 위해 미리 정의 된 "공급 업체 / 디스트로"기본값을 가지고 있지 않은 것 같습니다.

예 : 현재 설정을 확인하려면 :

$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...

예를 들어 단일 프로세스의 메모리를 제한하려면 :

$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed

실제로 RAM을 백그라운드 프로세스로 씹어 죽인 것을 보려면 :

$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
 0.0  0.0  2876
 102  0.2 44056
 103  0.5 85024
 103  1.0 166944
 ...
98.9  5.6 920552
99.1  4.3 718196
[1]+  Killed                  bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'

메모리 요청이 기하 급수적으로 증가하는 것에 주목하십시오.

앞으로는 "distro / vendors"가 SSH 및 그래픽 스택과 같은 중요한 요소에 대해 cgroup 우선 순위 및 제한 (시스템 단위를 통해)을 미리 구성하여 메모리가 고갈되지 않도록하겠습니다.


2

Ctrl- z를 눌러 프로그램을 일시 중단 할 수 있습니다 . 그런 다음 할 수 있습니다 kill %1(또는 작업 번호가 무엇이든 PID를 사용할 수 있습니다).

ulimit명령을 사용하여 프로세스에 사용 가능한 메모리 양을 제한 할 수 있습니다.


Ctrl-Z는 훌륭하지만 일반적으로 Matlab GUI를 실행 중이며 제어 터미널을 추적하지 못하므로 Ctrl-Z 키 누르기를 쉽게 실행할 수있는 방법이 없습니다. GUI에 포커스가있는 응용 프로그램에 SIGSTOP을 보내는 단축키가 있다면 좋을 것입니다!
nibot

kill -STOP <pid>Ctrl-Z와 동일한 작업을 실행할 수 있습니다 .
hlovdal

그렇습니다. 그러나 전체적인 문제는 그러한 상황에서 시스템이 너무 반응이 없어서 명령 프롬프트에 도달하는 데 시간이 오래 걸리는 것입니다.
nibot

1

CGroup을 사용하여 리소스 사용을 제한하고 이러한 문제를 방지 할 수 있습니다. https://en.wikipedia.org/wiki/Cgroups


답변에 필수 정보를 포함시키고 귀속 및 추가 정보를 위해 링크를 사용하십시오. 이 링크는 CGroups가 무엇인지 설명하지만 실제로 링크를 사용하여 문제를 해결하는 방법은 명확하지 않습니다. 질문에 대한 해결책을 설명하기 위해 답을 확장 할 수 있습니까? 감사.
fixer1234

0

GUI에 포커스가있는 응용 프로그램에 SIGSTOP을 보내는 단축키가 있다면 좋을 것입니다!

항상 고전적인 xkill명령이 있습니다 (시스템의 xorg-x11-apps-7.4-14.fc14.src.rpm). 대상 창을 죽이지 않고 SIGSTOP을 보내는 클론을 만드는 것이 너무 어렵지 않아야한다고 생각합니다.


키 조합을 누를 때 xkill을 빠르게 시작하려면 어떻게해야합니까?
nibot

확실하지 않습니다. 나는 gnome과 KDE에 프로그램을 시작하는 데 사용할 수있는 전역 단축키 기능이 있다고 가정합니다.
hlovdal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.