메모리가 부족한지 묻지 않고 리눅스가 프로세스를 죽이기 시작 할까?


66

메모리를 많이 사용하는 여러 프로그램 (2-5GB)을 연속적으로 실행하는 명령으로 셸 스크립트를 실행하고있었습니다. Killed터미널이 나에게보고 한 것처럼 스크립트 진행 상황을 확인하기 위해 다시 돌아 왔을 때 프로세스 일부가 있다는 사실에 놀랐 습니다. 여러 프로그램이 나중에 Killed시작된 프로그램 이전에 이미 성공적으로 완료 되었지만 나중에 모든 프로그램이 세그먼테이션 오류 (내 코드의 버그로 인한 것일 수도 있고 읽지 않을 수도 있음)에서 실패했습니다.

필자가 사용하고있는 특정 클러스터의 사용 내역을보고 누군가가 동시에 메모리 집약적 인 여러 프로세스를 실행하기 시작했으며 클러스터에서 사용할 수있는 실제 메모리 (및 스왑 공간까지)가 소진되었음을 알 수있었습니다. 내가 아는 한, 메모리 집약적 인 프로세스는 프로그램에 문제가 생길 때와 거의 같은 시간에 실행되기 시작했습니다.

메모리가 부족 해지면 Linux가 내 프로그램을 종료했을 가능성이 있습니까? 그리고 나중에 얻은 세그먼테이션 오류가 내 코드의 버그 대신 프로그램을 실행할 수있는 메모리 부족으로 인한 것일 수 있습니까?


2
메모리를 할당 할 때 메모리가 성공적으로 할당되었는지 확인하는 명령문이 있습니까? 코드에 버그가 있는지 또는 시스템의 메모리 부족 때문인지에 대한 단서를 제공해야합니다.
unxnut

4
LWN
0xC0000022L

답변:


72

할 수 있습니다.

Linux에서 발생할 수있는 두 가지 메모리 부족 조건이 있습니다. 발생하는 값은 sysctl vm.overcommit_memory( /proc/sys/vm/overcommit_memory) 의 값에 따라 다릅니다.

소개 :
커널은 '메모리 오버 커밋'을 수행 할 수 있습니다. 커널이 실제로 시스템에있는 것보다 많은 메모리를 프로그램에 할당 할 때입니다. 이것은 프로그램이 실제로 할당 한 모든 메모리를 사용하지 않기를 희망하며 이루어집니다.

overcommit_memory = 2

경우 overcommit_memory로 설정 2, 커널은 전혀 오버 커밋을 수행하지 않습니다. 대신 프로그램에 메모리가 할당되면 해당 메모리를 갖는 액세스가 보장됩니다. 시스템에 할당 요청을 충족시키기에 충분한 여유 메모리가 없으면 커널은 요청에 대한 실패 만 반환합니다. 상황을 정상적으로 처리하는 것은 프로그램에 달려 있습니다. 실제로 실패했을 때 할당이 성공했는지 확인하지 않으면 응용 프로그램에 종종 segfault가 발생합니다.

segfault의 경우 다음과 같은 출력에서 ​​다음과 같은 행을 찾아야합니다 dmesg.

[1962.987529] myapp[3303]: segfault at 0 ip 00400559 sp 5bc7b1b0 error 6 in myapp[400000+1000]

이는 at 0응용 프로그램이 초기화되지 않은 포인터에 액세스하려고 시도했음을 의미하며, 이는 메모리 할당 호출이 실패한 결과 일 수 있지만 유일한 방법은 아닙니다.

overcommit_memory = 0과 1

또는 overcommit_memory로 설정 하면 초과 커밋이 활성화되고 프로그램에서 실제로 사용 가능한 것보다 많은 메모리를 할당 할 수 있습니다.01

그러나 프로그램이 할당 된 메모리를 사용하려고 할 때 커널은 실제로 메모리를 만족시키기에 메모리가 충분하지 않다는 것을 알게되면 약간의 메모리를 다시 가져와야합니다. 먼저 캐시 플러시와 같은 다양한 메모리 정리 작업을 수행하려고 시도하지만 이것으로 충분하지 않으면 프로세스가 종료됩니다. 이 종료는 OOM-Killer에서 수행합니다. OOM-Killer는 시스템에서 어떤 프로그램이 어떤 메모리를 사용하고 있는지, 얼마나 오래 실행했는지, 누가 실행하고 있는지, 어떤 요소가 죽었는지 확인하기 위해 여러 가지 요소를 확인합니다.

프로세스가 종료되면 사용중인 메모리가 해제되고 메모리 부족 상태를 방금 발생시킨 프로그램에 필요한 메모리가 생깁니다.

그러나이 모드에서도 프로그램은 여전히 ​​할당 요청을 거부 할 수 있습니다. 때 overcommit_memory이다 0, 커널은 할당 요청을 거부 시작해야하는 경우에 추측을 시도합니다. 로 설정되면 1요청을 거부해야 할 시점을 결정하기 위해 어떤 결정을 사용하는지 잘 모르겠지만 매우 큰 요청을 거부 할 수 있습니다.

의 출력을보고 dmesg다음과 같은 메시지를 찾아 OOM-Killer가 관련되어 있는지 확인할 수 있습니다 .

[11686.043641] Out of memory: Kill process 2603 (flasherav) score 761 or sacrifice child
[11686.043647] Killed process 2603 (flasherav) total-vm:1498536kB, anon-rss:721784kB, file-rss:4228kB

그래서 두 가지 상황이 모두 일어난 것 같습니다.
NeutronStar

@Joshua 방금 답변을 업데이트했습니다. overcommit_memory0 또는 2로 설정된 경우에도 할당 실패가 발생할 수 있음을 언급하지
Patrick

OOM 킬러 를 게시물에 길들이는 링크를 편집하는 것이 좋습니다.
0xC0000022L

@ 0xC0000022L 감사합니다. 좋은 기사입니다 (약간 구식이지만). 나는 OOM 킬러를 제어하는 ​​것에 대해 아무것도 묻고 싶지 않았습니다. 왜냐하면 그것은 질문의 일부가 아니기 때문에 (그리고 짧은 주제가 아닙니다), 우리는 여기에 다른 많은 질문이 있습니다.
Patrick

1
@ mikeserv 나는 OOM 킬러의 행동이 그것을 제어하는 ​​것과 아무 관련이 없다고 말하지 않습니다. 문제는 리눅스가 그의 프로그램을 죽일 지 여부였다. 리눅스가 그렇게하지 못하게하는 방법은 리눅스가 실제로 그렇게하는지 확인해야합니다. 그리고이라면 overcommit_memory=2OOM 킬러도 활성화되지 않으므로 제어하는 ​​것은 무의미합니다. 그러나 우리가 그것이 OOM 킬러라는 것을 알게되면, 여기에서 다른 많은 질문과 답변으로 다루어지는 또 다른 주제가됩니다.
Patrick

16

진실은 시스템의 메모리 관리자로 인해 프로세스가 막혔 든 다른 것으로 인해 프로세스를 보는 방법에 관계없이 여전히 버그라는 것입니다. 메모리에서 방금 처리 한 모든 데이터는 어떻게 되었습니까? 저장되었습니다.

overcommit_memory=Linux OOM 관리를 구성하는 가장 일반적인 방법 이지만 다음과 같이 프로세스별로 조정할 수도 있습니다.

echo [-+][n] >/proc/$pid/oom_adj

-17위의를 사용하면 메모리 부족 관리에서 프로세스가 제외됩니다. 아마도 일반적으로 좋은 생각은 아니지만 버그 사냥을하는 경우 가치가있을 수 있습니다. 특히 그것이 OOM 인지 또는 코드 인지 알고 싶다면 . 긍정적으로 숫자를 늘리면 OOM 이벤트에서 프로세스가 종료 될 가능성이 높아져 메모리 부족 상황에서 코드의 복원력을 향상시키고 필요할 때 정상적으로 종료 할 수 있습니다.

다음과 같이 프로세스 당 OOM 핸들러의 현재 설정을 확인할 수 있습니다.

cat /proc/$pid/oom_score 

그렇지 않으면 자살을 갈 수 있습니다.

sysctl vm.panic_on_oom=1
sysctl kernel.panic=X

메모리 부족 상태에서 컴퓨터가 재부팅되도록 설정합니다. X재부팅 전에 커널 패닉 후 컴퓨터가 정지되는 시간 (초)으로 위의 값을 설정합니다 . 사나워

그리고 어떤 이유로 든 당신이 그것을 좋아한다고 결정하면 그것을 지속시킵니다.

echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf

내가 사용하는 공유 클러스터입니다. 다른 사용자가 동의없이 다시 시작하는 것을 좋아하지 않을 것이라고 확신합니다.
NeutronStar 2016 년

3
@Joshua-나는 누군가가 그것을 좋아한다는 것을 매우 심각하게 의심합니다-심지어 그것은 Asimov의 로봇 공학 법칙을 무시합니다. 반면에, 앞에서 언급했듯이 프로세스 당 OOM을 다른 방식으로 구성 할 수도 있습니다. 즉, 프로세스 당 자신의 정의 된 규칙 세트를 기반으로 개인적으로 심사 할 수 있습니다. 이런 종류의 일은 공유 클러스터 시나리오에서 특히 유용 할 것 같습니다.
mikeserv 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.