저는 350MB RAM과 2GB 스왑 공간을 갖춘 가상 머신에서 Vagrant를 통해 FreeBSD 12를 실행하고 있습니다.
내가 실행하면 :
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
예상했던 대로 작동했습니다. 5개의 프로세스를 시작하여 각각 400MB(프로세스당 2*200MB)를 소비했습니다.
그러나 제거하면 sleep 10
:
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
perl -e '$a="x"x200_000_000;sleep 1000' &
FreeBSD는 2개의 일자리를 죽였습니다.
왜?
어떻게 피할 수 있나요?
5개 이상 실행하는 경우:
perl -e '$a="x"x200_000_000;sleep 1000' & sleep 10
그런 다음 메모리 부족으로 인해 최신 항목이 종료될 것으로 예상했습니다. 그러나 FreeBSD는 Perl 작업을 무작위로 선택하여 종료하는 것 같습니다.
다음의 스크린샷은 다음과 같습니다 top
.
last pid: 3529; load averages: 1.45, 0.62, 0.34 up 0+00:17:14 21:49:30
29 processes: 5 running, 24 sleeping
CPU: 0.6% user, 0.0% nice, 34.5% system, 6.6% interrupt, 58.3% idle
Mem: 150M Active, 1080K Inact, 41M Laundry, 108M Wired, 39M Buf, 2256K Free
Swap: 2423M Total, 873M Used, 1550M Free, 36% Inuse, 33M In, 29M Out
PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
3521 vagrant 1 29 0 400M 53M RUN 1 0:03 25.98% perl
3525 vagrant 1 24 0 400M 52M RUN 1 0:03 4.11% perl
3527 vagrant 1 25 0 400M 53M RUN 0 0:02 4.09% perl
3523 vagrant 1 24 0 400M 52M RUN 1 0:03 3.53% perl
807 root 7 52 0 20M 1672K sigwai 1 0:00 0.07% VBoxService
답변1
너무 오래;
왜?
자원이 고갈되면 누가 살아남을지 보장할 수 없습니다. 과도한 메모리 사용량은 목표를 제공합니다.
어떻게 피할 수 있나요?
메모리 할당 시 주의하세요. 필요한 것보다 더 많이 할당하지 마십시오. 많은 양의 메모리를 서둘러 할당해야 하는 경우 "사용 가능한" 메모리를 모니터링하여 OOM이 트리거되지 않는지 확인하세요.
바라보다FreeBSD 메모리 위키그리고FreeBSD는 메모리를 어떻게 할당하나요?
조심하세요 여기 용이 있어요
이것은 단지 추측일 뿐입니다. 당신은 그것을 건드리지 않았으므로 당신이 분명히 알 수 있는 것을 언급하겠습니다:
시스템 리소스가 제한되어 있습니다. RAM은 350MB에 불과하지만 작업을 위한 스왑 공간은 충분합니다. 아주 작은 휴면 시간이 있는 한, 페이지 출력 데몬은 더티 페이지의 일부 또는 전체를 실행하고 교환할 시간을 갖습니다. 지체 없이 경기가 시작되었습니다.
활성 및 비활성 큐에는 클린 페이지와 더티 페이지가 포함됩니다. 부족을 완화하기 위해 메모리가 회수되면 페이지 데몬은 비활성 대기열의 헤드에서 깨끗한 페이지를 해제합니다. 더티 페이지는 먼저 스왑이나 파일 시스템으로 페이징하여 지워야 합니다. 이는 많은 작업이므로 페이지 데몬은 지연 처리를 위해 해당 작업을 세탁 대기열로 이동합니다.
——우수 기사에서 발췌FreeBSD에서 스왑 살펴보기
NUMA 시스템에는 여러 페이지 데몬과 세탁 스레드가 있을 수 있다는 점은 주목할 가치가 있습니다.
당신은 그들이 순서대로 죽임을 당할 것이라고 예상합니다. 그러나 시스템은 그러한 보장을 제공하지 않습니다. 이건 극단적인 경우이고 시스템은 완전히 마피아야"남자는 남자가 해야 할 일을 해야 한다.". 배후에는 일종의 "질서"가 있을 것입니다.
종료할 프로세스를 찾기 위해 커널은 실행 가능한 각 프로세스의 메모리 사용량을 추정하고 사용량이 가장 많은 프로세스를 선택합니다.
하지만 프로세스가 동일하므로 도움이 되지 않습니다. 그런 다음 프로세스가 완전히 순차적으로 실행되는지, 아니면 다른 시스템 프로세스가 세탁 목록의 프로세스를 삑삑거리고 페이지 순서를 지정하는지에 대해 자세히 논의하겠습니다. 따라서 OOM이 발생하면 시스템은 살아남으려고 노력하지만 결정론적인 보장을 제공하지는 않습니다.
프로세스 우선순위(양호한 수준)를 존중하고 싶다고 주장하거나 특정 메모리 우선순위를 설정할 수도 있습니다. 그런 건 존재하지 않아내 거지식. OOM으로부터 프로세스를 보호할 수 있지만 이는 다음 용도로 예약되어야 합니다.진짜 진짜 진짜중요하고 잘 테스트된 시스템 서비스입니다.
주의깊게 관찰하세요
문제가 발생하면 콘솔 로그에 기록됩니다. 이보다 더 복잡한 상황을 디버깅하는 경우 도움이 될 수 있습니다.
주로 다음과 같은 것을 찾고 있을 것입니다:
pid . . ., was killed: failed to reclaim memory
pid . . ., was killed: a thread waited too long to allocate a page
pid . . ., was killed: out of swap space
kernel: swap_pager
이러한 로그 파일 중 몇 가지를 살펴보고 싶을 수도 있지만 /var/log
가장 흥미로운 파일은 다음과 같습니다.
dmesg | grep -e killed -e swap_pager
동조
OOM 동작을 조정하려면 다음 sysctls가 유용할 것입니다.
vm.pageout_oom_seq: back-to-back calls to oom detector to start OOM
vm.panic_on_oom: panic on out of memory instead of killing the largest process
vm.pfault_oom_wait: Number of seconds to wait for free pages before retrying the page fault handler
vm.pfault_oom_attempts: Number of page allocation attempts in page fault handler before it triggers OOM handling
vm.v_pageout_free_min: Min pages reserved for kernel
vm.pageout_oom_seq: back-to-back calls to oom detector to start OOM
vm.pageout_lock_miss: vget() lock misses during pageout
vm.disable_swapspace_pageouts: Disallow swapout of dirty pages
vm.pageout_update_period: Maximum active LRU update period
예를 들어 vm.pageout_oom_seq
기본값은 12입니다. 이 값을 낮추면 OOM은 pagedaemon 진행 부족에 더욱 민감해집니다.
하지 말아야 할 것
문제를 더 깊이 파고들면 몇 가지 흥미로운 징후를 발견할 수 있습니다. 귀하의 사례는 당연히 하나의 예이므로 귀하가 정확히 무엇을 달성하려고 하는지 우리는 알 수 없습니다.
당신이 보면참고(1)당신은 깃발을 찾을 수 있습니다 P_SWAPPINGOUT
. 수행 중인 작업에 따라 자신의 프로세스가 실제로 교환 중인지 확인하기 위해 세심한 주의를 기울일 수 있습니다. 현실 세계에서는 할당하기 전에 사용 가능한 메모리를 확인하는 것이 더 나을 것입니다.
이러한 표시를 보면 당신이 그것을 볼 때 부당한 유혹을 받을 수도 있습니다 P_PROTECTED
. 다른 곳에서는 이를 madvise(MADV_PROTECT)라고도 합니다. 이는 OOM으로부터 보호되는 프로세스입니다.
하다아니요그것을 사용하십시오.
이 값은 다음 명령을 사용하여 프로세스에 대해 쉽게 설정할 수 있습니다.보호(1)
하다아니요그것을 사용하십시오.
rc 서비스의 경우 ${name}_oomprotect
rc.conf
변수를 로 설정하여 설정할 수 있습니다 “YES”
.
하다아니요그것을 사용하십시오.
합리적인 시스템 설정과"충분한"공간을 교환하면 시스템이 중단됩니다.
합리적인 방식으로 메모리를 할당하는 프로세스를 작성했다면 이에 대해 생각해 볼 수도 있습니다. 이 프로세스가 나에게 정말로 중요하고 메모리 할당을 과도하게 사용하거나 누수가 있는 다른 오작동 프로세스가 있다는 것을 알고 있는 경우에만 이 작업을 수행할 것입니다.
좋은 글이 있네요FreeBSD가 PostgreSQL을 종료하지 못하도록 방지(OOM Killer 방지라고도 함)하지만 나 자신은 그렇게 하지 않을 것이다. 시스템을 능가하려고 하면 위험한 위치에 놓이게 됩니다. OOM은 생존 모드이므로 세계의 질서 있는 붕괴에 의존하는 내용을 작성해서는 안 됩니다.