스왑 런 메모리 사용량으로 인한 시스템 정지 / 무응답 방지


46

프로세스에 많은 메모리가 필요한 경우 시스템은 다른 모든 프로세스를 스왑 파일로 이동합니다. 그것을 포함하여 X11 서버 또는 터미널과 같은 필요한 프로세스가 보입니다.

따라서 프로세스가 제한없이 계속 할당되면 해당 프로세스가 OOM-killer에 의해 종료 될 때까지 모든 것이 응답하지 않습니다. 내 노트북은 특히 합리적인 것으로 보이며 매우 심하게 반응합니다. 방금 마우스 커서조차도 이동할 수없는 프로세스 종료를 기다리는 전체 시간을 보냈습니다.

어떻게 이것을 피할 수 있습니까?

1) 스왑 비활성화 => 종종 많은 프로세스를 시작한 다음 비활성화됩니다. 비활성 항목은 스왑으로 이동해야합니다.

2) SSD 확보 => 너무 비싸다

3) 최대 메모리 ulimit =>를 설정하지만 프로그램에 공명 가능한 대용량 메모리가 필요한 경우 실패합니다. 문제는 너무 많이 사용하는 것이 아니라 다른 프로세스를 억제한다는 것입니다.

4) 중요한 프로그램 (X11, bash, kill, top, ...)을 메모리에 유지하고 그와 교환하지 마십시오 =>이 작업을 수행 할 수 있습니까? 방법? 아마도 큰 프로그램 만 바꾸겠습니까?

5)?


그리고 ti는 다시 일어났다 : (파이어 폭스가 실행되는 동안 gcc를 시작, 30 분 동안 모든 것이 차단되었습니다. 마우스 움직임, 전자 책 읽기 없음
BeniBela

나는 당신이 원하는 것을 이해하지 못합니다. 시스템이 보유한 리소스를 사용하여 마술처럼 빠르게 일을 하시겠습니까? 더 많은 메모리를 사용하는 프로세스를 더 빨리 종료 하시겠습니까?
David Schwartz

실제로 필요한 것은 더 많은 RAM입니다. 또는 "비활성"백그라운드 작업이 적습니다.
Daniel B

2
당신은 사용할 수 있습니다 Alt + SysRq를 + F를 실행하기 위해 OOM 킬러를 강제로 키 조합을. 이로 인해 시스템이 콘솔을 열기 위해 대기하는 데 필요한 시간이 오래 걸리므로 프로세스를 종료 할 수 있습니다.
hololeap

내가 틀렸다면 수정하지만이 문제는 실제로 시스템이 존재해야하지만 존재하지 않는 디스크 스왑 공간을 찾고있는 것처럼 들립니다 (스왑 파티션이 너무 작습니다). 스왑 공간이 충분하지 않으면 시스템에서 사용 가능한 공간을 찾기 위해 하드 드라이브 (또는 ssd)가 "쓰레질"됩니다.
mchid

답변:


43

TL; DR

짧은 임시 / 응답

  • 가장 쉬움 : 스왑 파티션이 작고 커널이 느린 스토리지에서 프로세스를 실행하여 메모리 제한이 없다는 거짓말을 피하십시오.
    • 큰 스왑을 사용하면 OOM (메모리 관리자가 아님)이 조만간 조치를 취하지 않습니다. 일반적으로 가상 메모리에 따라 설명되며 과거의 경험에서 전체 스왑이 채워질 때까지 물건을 죽이지 않았으므로 스 래싱 및 크롤링 시스템은 ...
  • 최대 절전 모드로 전환해야합니까?
    • 시도 / 문제 : 일부 ulimits를 설정하십시오 (예 : check ulimit -v, 및의 as옵션을 사용하여 하드 또는 소프트 한계를 설정하십시오 limits.conf). 이것은 잘 작동했지만 WebKit 도입 덕분에 gigacage많은 그놈 앱은 이제 무제한 주소 공간을 기대하고 실행되지 않습니다!
    • 시도 / 문제 다음 오버 커밋 정책과 비율을 관리하려고 예를 들어 (이 문제를 완화하는 또 다른 방법입니다 sysctl vm.overcommit_memory, sysctl vm.overcommit_ratio하지만이 방법은 나를 위해 작동하지 않았다.
    • 어려움 / 복잡함 : cgroup 우선 순위를 가장 중요한 프로세스 (예 : ssh)에 적용 해보십시오. 그러나 현재 cgroup v1에는 번거 롭습니다 (v2가 쉬워 질 것입니다) ...

나는 또한 발견했다 :

  • 더 작은 스왑 공간에 대한 위의 조언을 뒷받침하는 또 다른 스택 교환 항목 .
  • 현재 상황에 대한 해결 방법으로 thrash-protect 와 같은 것을 시도 할 수 있습니다.

장기 솔루션

몇 가지 업스트림 패치가 안정적인 배포 커널로 들어가기를 기다립니다. 또한 배포판 공급 업체가 커널 기본값을 더 잘 조정하고 시스템화 된 cgroup을 더 잘 활용하여 데스크톱 버전에서 GUI 응답 성을 우선시하기를 바랍니다.

관심있는 패치들 :

따라서 잘못된 사용자 공간 코드와 distro config / defaults는 잘못이 아닙니다. 커널이 더 잘 처리 할 수 ​​있습니다.

이미 고려 된 옵션에 대한 의견

1) 스왑 비활성화

최소한 작은 스왑 파티션을 제공하는 것이 좋습니다 ( 현대 시스템에서는 실제로 스왑이 필요합니까? ). 스왑을 비활성화하면 사용되지 않은 페이지가 스왑되지 않을뿐만 아니라 메모리 할당에 대한 커널의 기본 휴리스틱 오버 커밋 전략 ( Overcommit_memory = 0의 휴리스틱은 무엇을 의미합니까? ) 에도 영향을 줄 수 있습니다. 휴리스틱은 스왑 페이지에 포함됩니다. 스왑이 없으면 오버 커밋은 휴리스틱 (0) 또는 항상 (1) 모드에서 작동 할 수 있지만 스왑 없음과 절대 (2) 오버 커밋 전략의 조합은 끔찍한 아이디어 일 것입니다. 따라서 대부분의 경우 스왑이 성능을 저하시키지 않을 것입니다.

예를 들어, 처음에는 일회성 작업을 위해 메모리에 닿지 만 그 메모리를 해제하지 못하고 백그라운드를 계속 실행하는 장기 실행 프로세스를 생각해보십시오. 커널은 프로세스가 끝날 때까지 RAM을 사용해야합니다. 스왑이 없으면 커널은 실제로 RAM을 적극적으로 사용하려는 다른 것을 위해 페이지를 넘길 수 없습니다. 또한 얼마나 많은 개발자가 게으르고 사용 후 메모리를 명시 적으로 비우지 않는지 생각해보십시오.

3) 최대 메모리 ulimit 설정

프로세스 당 적용되며 프로세스가 시스템에 실제로 더 많은 메모리를 요청해서는 안된다는 합리적인 가정 일 것입니다! 따라서 고독한 미친 프로세스가 여전히 관대하게 설정되는 동안 스 래싱을 유발하는 것을 막는 것이 유용 할 것입니다.

4) 중요한 프로그램 (X11, bash, kill, top 등)을 메모리에 유지하고 절대로 스왑하지 마십시오.

좋은 생각이지만, 그 프로그램은 적극적으로 사용하지 않는 메모리를 낭비합니다. 프로그램이 적당한 양의 메모리 만 요청하는 경우 허용 될 수 있습니다.

systemd 232 릴리스 는 이것을 가능하게하는 몇 가지 옵션을 추가했습니다 .'MemorySwapMax = 0 '을 사용하여 ssh와 같은 장치 (서비스)가 메모리가 스왑 아웃되는 것을 방지 할 수 있다고 생각합니다.

그럼에도 불구하고 메모리 액세스 우선 순위를 정하는 것이 더 좋습니다.

긴 설명

리눅스 커널은 서버 워크로드에 맞게 조정되었으므로 GUI 응답 성은 슬프게도 이차적 인 관심사였습니다 ... Ubuntu 16.04 LTS 데스크톱 에디션의 커널 메모리 관리 설정은 다른 서버 에디션과 다르지 않았습니다. 서버로 일반적으로 사용되는 RHEL / CentOS 7.2의 기본값과도 일치합니다.

응답 성을위한 OOM, ulimit 및 거래 무결성

스 래싱 스왑 (예 : 작업 시간이 짧은 메모리에서 읽고 쓰는 페이지가 실제 RAM을 초과하는 경우)은 항상 스토리지 I / O를 잠급니다. 커널 마법사는 프로세스를 종료하지 않고 시스템을 저장할 수 없습니다. 또는 두 ...

최근 커널에서 Linux OOM 조정이이 작업 세트가 실제 메모리 상황을 초과하고 프로세스를 종료한다는 것을 인식하기를 바라고 있습니다. 그렇지 않으면 스 래싱 문제가 발생합니다. 문제는 스왑 파티션이 큰 경우 커널이 커밋을 초과하여 메모리 요청을 처리하는 동안 시스템에 여전히 여유 공간이있는 것처럼 보일 수 있지만 작업 세트는 스왑으로 넘쳐서 스토리지를 효과적으로 처리하려고 시도하는 것입니다 RAM입니다.

서버에서 결정된, 느리고 데이터 손실, 트레이드 오프에 대한 스 래싱의 성능 저하를 수용합니다. 데스크탑에서는 트레이드 오프가 다르므로 사용자는 응답 성을 유지하기 위해 약간의 데이터 손실 (프로세스 희생)을 선호합니다.

이것은 OOM에 대한 멋진 비유였습니다. oom_pardon, 일명 내 xlock을 죽이지 마십시오.

덧붙여서, OOMScoreAdjust더 중요한 것으로 간주되는 OOM 킬 프로세스를 방지하고 무게를 줄이는 데 도움이되는 또 다른 시스템 옵션입니다.

버퍼링 된 쓰기

" 백그라운드 쓰기 저장을하지 말 것" 은 프로세스 호그 RAM이 다른 스왑 아웃 (디스크에 쓰기)을 유발하고 디스크에 대한 대량 쓰기가 IO를 원하는 다른 것을 멈추게하는 일부 문제를 피하는 데 도움이 된다고 생각 합니다. 스 래싱 문제 자체의 원인은 아니지만 응답 성이 전반적으로 저하됩니다.

ulimits 제한

ulimits의 한 가지 문제점은 한계를 계산하는 것이 가상 메모리 주소 공간 (물리적 공간과 스왑 공간의 결합을 의미 함)에 적용된다는 것입니다. 에 따라 man limits.conf:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

따라서 물리적 RAM 사용에만 적용되도록 ulimit를 설정해도 더 이상 사용할 수 없습니다. 금후

      as
          address space limit (KB)

유일하게 존경받는 튜너 블 인 것 같습니다.

불행히도 WebKit / Gnome의 예에서 자세히 설명했듯이 가상 주소 공간 할당이 제한되어 있으면 일부 응용 프로그램을 실행할 수 없습니다.

cgroups는 미래에 도움이 될까요?

현재는 번거롭지 만 일부 커널 cgroup 플래그 cgroup_enable=memory swapaccount=1(예 : grub config) 를 활성화 한 다음 cgroup 메모리 컨트롤러를 사용하여 메모리 사용을 제한 할 수 있습니다.

cgroup에는 'ulimit'옵션보다 고급 메모리 제한 기능이 있습니다. CGroup v2 는 ulimits 작동 방식 개선을위한 힌트를 제공합니다.

결합 된 메모리 + 스왑 계정 및 제한은 스왑 공간에 대한 실제 제어로 대체됩니다.

CGroup 옵션은 시스템 리소스 제어 옵션을 통해 설정할 수 있습니다 . 예 :

  • 메모리 높음
  • 메모리 맥스

다른 유용한 옵션은

  • IOWeight
  • CPUShares

여기에는 몇 가지 단점이 있습니다.

  1. 간접비. 현재 도커 설명서에는 1 % 추가 메모리 사용 및 10 % 성능 저하가 언급되어 있습니다 (메모리 할당 작업과 관련하여 실제로 지정되지는 않음).
  2. Cgroup / systemd 제품은 최근에 대대적으로 재 작업되었으므로, 플럭스 업스트림은 Linux 배포판 공급 업체가이를 해결하기를 기다리고 있다는 의미입니다.

CGroup v2 에서는 memory.high프로세스 그룹이 메모리 사용을 조절하고 관리하는 데 좋은 옵션이어야한다고 제안합니다 . 그러나이 인용은 메모리 부족 상황을 모니터링하는 데 더 많은 작업이 필요하다는 것을 암시합니다 (2015 년 기준).

워크로드에 더 많은 메모리가 필요한지 여부를 판별하려면 메모리 부족으로 인해 워크로드가 메모리 부족으로 인해 얼마나 많은 영향을 받는지 측정해야합니다. 불행히도 메모리 압력 모니터링 메커니즘은 아직 구현되지 않았습니다.

systemd 및 cgroup 사용자 공간 도구가 복잡하기 때문에 적절한 것을 설정하고 더 활용할 수있는 간단한 방법을 찾지 못했습니다. 우분투에 대한 cgroup 및 systemd 문서는 훌륭하지 않습니다. 추후 작업은 데스크톱 버전의 배포판에서 cgroup을 활용하고 시스템화하여 메모리 부족으로 인해 ssh 및 X-Server / window manager 구성 요소가 CPU, 물리적 RAM 및 스토리지 IO에 우선적으로 액세스하여 프로세스와의 경쟁을 피할 수 있도록해야합니다. 바쁜 스와핑. 커널의 CPU 및 I / O 우선 순위 기능은 한동안 사용되었습니다. 부족한 물리적 RAM에 우선적으로 액세스하는 것 같습니다.

그러나 CPU 및 IO 우선 순위조차도 적절하게 설정되지 않았습니다! 내가 말할 수있는 한, 체계화 된 cgroup 제한, CPU 공유 등을 확인했을 때 우분투는 사전 정의 된 우선 순위에 구워지지 않았습니다. 예 : 나는 달렸다 :

systemctl show dev-mapper-Ubuntu\x2dswap.swap

ssh, samba, gdm 및 nginx의 동일한 출력과 비교했습니다. GUI 및 원격 관리 콘솔과 같은 중요한 것은 스 래싱이 발생할 때 다른 모든 프로세스와 동등하게 싸워야합니다.

16GB RAM 시스템의 메모리 제한 예

최대 절전 모드를 사용하려고했기 때문에 큰 스왑 파티션이 필요했습니다. 따라서 ulimits 등으로 완화하려고합니다.

ulimit

내가 넣어 * hard as 16777216에서 /etc/security/limits.d/mem.conf단일 프로세스가 물리적으로 가능한 것보다 더 많은 메모리를 요청하도록 허용 할 것 같은. 스 래싱을 모두 방지하지는 않지만 욕심 많은 메모리 사용 또는 메모리 누수를 가진 단일 프로세스만으로 스 래싱을 유발할 수 있습니다. 본 적이 예 : 나는 gnome-contactsExchange 서버에서 전체 주소 목록을 업데이트 같은 일상적인 일을 할 때 8GB 메모리 +를 빨아 ...

RAM을 씹는 그놈 연락처

에서 볼 수 있듯이 ulimit -S -v많은 배포판에서는이 하드 및 소프트 제한이 '무제한'으로 설정되어 있습니다. 이론적으로 프로세스는 많은 메모리를 요청하지만 서브 세트를 적극적으로 사용하고 24GB의 RAM이 있다고 생각하여 행복하게 실행될 수 있습니다. 시스템에는 16GB 만 있습니다. 위의 하드 한계는 커널이 욕심 많은 추론 적 메모리 요청을 거부 할 때 제대로 실행 된 프로세스를 중단시킵니다.

그러나 그놈 연락처와 같은 미친 것들을 포착하고 데스크탑 응답 성을 잃지 않고 "사용 가능한 메모리가 부족합니다"라는 오류가 발생합니다.

여기에 이미지 설명을 입력하십시오

주소 공간에 대한 ulimit 설정 (가상 메모리)

불행히도, 일부 개발자는 가상 메모리를 무한한 리소스로 생각하고 가상 메모리에서 ulimit를 설정하면 일부 앱이 중단 될 수 있습니다. 예를 들어 WebKit (일부 그놈 앱에 의존) gigacage은 가상 메모리 양을 할당하려고 시도 하는 보안 기능을 추가 FATAL: Could not allocate gigacage memory했으며 건방진 힌트로 오류가 Make sure you have not set a virtual memory limit발생했습니다. 해결 방법GIGACAGE_ENABLED=no보안상의 이점은 잊어 버렸지 만 가상 메모리 할당을 제한 할 수없는 것도 보안 기능 (예 : 서비스 거부를 방지 할 수있는 리소스 제어)을 잊어 버렸습니다. 아이러니하게도, 기가 케이지와 그놈 개발자 사이에서 메모리 할당을 제한하는 것 자체가 보안 제어라는 것을 잊어 버리는 것 같습니다. 그리고 슬프게도, gigacage에 의존하는 그놈 앱이 명시 적으로 더 높은 제한을 요구하지 않으므로 소프트 제한 조차도이 경우에 문제가 발생한다는 것을 알았습니다.

공평하게 말하자면, 커널이 가상 메모리 대신 상주 메모리 사용을 기반으로 메모리 할당을 거부하는 더 나은 작업을 수행했다면 가상 메모리를 무제한으로 사용하는 것은 덜 위험합니다.

지나치게 커밋하다

응용 프로그램의 메모리 액세스가 거부되고 오버 커밋을 중지하려면 아래 명령을 사용하여 메모리 부족 상태에서 시스템의 동작을 테스트하십시오.

필자의 경우 기본 커밋 비율은 다음과 같습니다.

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

그러나 오버 커밋을 비활성화하고 비율을 적용하도록 정책을 변경할 때만 효과가 있습니다.

sudo sysctl -w vm.overcommit_memory=2

이 비율은 전체적으로 24GB의 메모리 만 할당 할 수 있음을 나타냅니다 (16GB RAM * 0.5 + 16GB SWAP). 따라서 OOM이 표시되는 것을 결코 보지 못하고 프로세스가 스왑의 메모리에 지속적으로 액세스 할 가능성이 거의 없습니다. 그러나 전반적인 시스템 효율성도 희생 될 것입니다.

개발자가 메모리 할당 요청을 거부하는 OS를 정상적으로 처리하지 못하는 경우가 많기 때문에 많은 응용 프로그램이 중단됩니다. 그것은 다양한 앱 충돌의 더 빈번한 위험으로 스 래싱 (하드 리셋 후 모든 작업을 잃음)으로 인해 잠금이 끊어 질 위험을 때때로 상쇄합니다. 필자의 테스트에서 시스템에 메모리 부족이 발생했을 때 데스크톱 자체가 충돌하여 메모리를 할당 할 수 없기 때문에별로 도움이되지 않았습니다. 그러나 최소한 콘솔과 SSH는 여전히 작동했습니다.

VM 오버 커밋 메모리 작업 에 더 많은 정보가 있습니까 ?

sudo sysctl -w vm.overcommit_memory=0그럼에도 불구하고 전체 데스크톱 그래픽 스택과 응용 프로그램의 충돌로 인해 기본값으로 되돌리기로 선택했습니다 .


3
이것은 내가이 문제에 대해 본 최고의 글이며, "더 많은 RAM을 사십시오!" 언급하지 않은 한 가지는 커널 구성 옵션이 어떻게 작동하는지입니다. 예를 들어, 사용 된 preemtion 모델 또는 사용 된 I / O 스케줄러가 이것에 큰 영향을 미칩니 까?
hololeap

2
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this. 이것에 대한 증거가 있습니까? 나는 스왑 구성없이 잘 커널의 overcommit을 믿지
ygrek

@ygrek, 고마워, 문구는 공정하게 잘못 보일 것입니다. 오버 커밋은 절대 오버 커밋 모드 (2)를 선택하지 않으면 스왑없이 계속 작동합니다. 기본 휴리스틱 오버 커밋 모드 (0) 또는 항상 커밋 (1) 모드는 여전히 스왑없이 작동합니다. 스왑을 끄면 오버 커밋 코드가 메모리를 할당하는 기능 (그리고 특히 어떤 모드에 영향을 미쳤는지)이 손상되었음을 읽은 곳을 기억할 수 없습니다. 운없이 다시 구글에 올렸지 만, 이것은 반 유용한 게시물이었다 : stackoverflow.com/questions/38688824/… 나는 대답을 적절히 편집 할 것이다.
JPvRiel

백그라운드 쓰기 저장 패치가 도움이되기를 바랐지만 매우 새로운 커널 (4.14.81)을 사용 중이며 디스크 I / O가 많은 경우 (스왑이 원인인지 여부에 관계없이) 상당한 응답 성 문제에 직면했습니다. 장치 관리자 또는 LUKS 암호화가 어떻게 든 성능 문제를 일으키는 지 궁금합니다. 이런 종류의 문제를 디버깅하는 방법은 거의 없습니다.
다리우스 Jahandarie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.