Python subprocess.Popen“OSError : [Errno 12] 메모리를 할당 할 수 없습니다.”


114

참고 : 이 질문은 원래 여기에서 요청 되었지만 실제로 수용 가능한 답변을 찾지 못했지만 바운티 시간이 만료되었습니다. 원래 질문에 제공된 모든 세부 정보를 포함하여이 질문을 다시 요청합니다.

python 스크립트는 sched 모듈을 사용하여 60 초마다 클래스 함수 세트를 실행 합니다.

# sc is a sched.scheduler instance
sc.enter(60, 1, self.doChecks, (sc, False))

스크립트는 여기에 있는 코드를 사용하여 데몬 화 된 프로세스로 실행됩니다 .

doChecks의 일부로 호출되는 여러 클래스 메소드는 시스템 통계를 얻기 위해 서브 프로세스 모듈을 사용하여 시스템 함수를 호출합니다.

ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE).communicate()[0]

전체 스크립트가 다음 오류와 함께 충돌하기 전에 일정 시간 동안 정상적으로 실행됩니다.

File "/home/admin/sd-agent/checks.py", line 436, in getProcesses
File "/usr/lib/python2.4/subprocess.py", line 533, in __init__
File "/usr/lib/python2.4/subprocess.py", line 835, in _get_handles
OSError: [Errno 12] Cannot allocate memory

스크립트가 충돌 한 후 서버에서 free -m의 출력은 다음과 같습니다.

$ free -m
                  total       used       free     shared     buffers    cached
Mem:                894        345        549          0          0          0
-/+ buffers/cache:  345        549
Swap:                 0          0          0

서버에서 CentOS 5.3을 실행 중입니다. 내 CentOS 상자에서 또는 동일한 문제를보고하는 다른 사용자와 함께 재현 할 수 없습니다.

원래 질문에서 제안한 것처럼 이것을 디버깅하기 위해 여러 가지를 시도했습니다.

  1. Popen 호출 전후에 free -m의 출력을 로깅합니다. 메모리 사용량에는 큰 변화가 없습니다. 즉, 스크립트가 실행될 때 메모리가 점진적으로 사용되지 않습니다.

  2. Popen 호출에 close_fds = True를 추가했지만 차이가 없었습니다. 스크립트가 여전히 동일한 오류로 충돌했습니다. 여기여기에서 제안 합니다 .

  3. 여기에 제안 된대로 RLIMIT_DATA 및 RLIMIT_AS 모두에서 (-1, -1)을 표시 한 rlimits를 확인했습니다 .

  4. 한 기사 는 스왑 공간이없는 것이 원인 일 수 있지만 실제로 필요할 때 스왑을 사용할 수 있다고 제안했으며 (웹 호스트에 따라) 이것은 여기 에서 가짜 원인으로도 제안되었습니다 .

  5. 그 파이썬 소스 코드 및 주석에 의해 백업으로 .communicate ()를 사용하여 동작하기 때문에 프로세스는 폐쇄되고 여기가 .

전체 검사는 GitHub에서 442 행에서 정의 된 getProcesses 함수와 함께 찾을 수 있습니다. 이는 520 행에서 시작하는 doChecks ()에 의해 호출됩니다.

스크립트는 충돌 전에 다음 출력과 함께 strace로 실행되었습니다.

recv(4, "Total Accesses: 516662\nTotal kBy"..., 234, 0) = 234
gettimeofday({1250893252, 887805}, NULL) = 0
write(3, "2009-08-21 17:20:52,887 - checks"..., 91) = 91
gettimeofday({1250893252, 888362}, NULL) = 0
write(3, "2009-08-21 17:20:52,888 - checks"..., 74) = 74
gettimeofday({1250893252, 888897}, NULL) = 0
write(3, "2009-08-21 17:20:52,888 - checks"..., 67) = 67
gettimeofday({1250893252, 889184}, NULL) = 0
write(3, "2009-08-21 17:20:52,889 - checks"..., 81) = 81
close(4)                                = 0
gettimeofday({1250893252, 889591}, NULL) = 0
write(3, "2009-08-21 17:20:52,889 - checks"..., 63) = 63
pipe([4, 5])                            = 0
pipe([6, 7])                            = 0
fcntl64(7, F_GETFD)                     = 0
fcntl64(7, F_SETFD, FD_CLOEXEC)         = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7f12708) = -1 ENOMEM (Cannot allocate memory)
write(2, "Traceback (most recent call last"..., 35) = 35
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/agent."..., 52) = 52
open("/home/admin/sd-agent/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/daemon.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/home/admin/sd-agent/dae"..., 60) = 60
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/agent.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/agent."..., 54) = 54
open("/usr/lib/python2.4/sched.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/sched"..., 55) = 55
fstat64(8, {st_mode=S_IFREG|0644, st_size=4054, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "\"\"\"A generally useful event sche"..., 4096) = 4054
write(2, "    ", 4)                     = 4
write(2, "void = action(*argument)\n", 25) = 25
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/checks"..., 60) = 60
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/bin/sd-agent/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python24.zip/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/plat-linux2/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOMEM (Cannot allocate memory)
open("/usr/lib/python2.4/lib-tk/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/lib-dynload/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/lib/python2.4/site-packages/checks.py", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
write(2, "  File \"/usr/bin/sd-agent/checks"..., 64) = 64
open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/subpr"..., 65) = 65
fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "# subprocess - Subprocesses with"..., 4096) = 4096
read(8, "lso, the newlines attribute of t"..., 4096) = 4096
read(8, "code < 0:\n        print >>sys.st"..., 4096) = 4096
read(8, "alse does not exist on 2.2.0\ntry"..., 4096) = 4096
read(8, " p2cread\n        # c2pread    <-"..., 4096) = 4096
write(2, "    ", 4)                     = 4
write(2, "errread, errwrite)\n", 19)    = 19
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
open("/usr/lib/python2.4/subprocess.py", O_RDONLY|O_LARGEFILE) = 8
write(2, "  File \"/usr/lib/python2.4/subpr"..., 71) = 71
fstat64(8, {st_mode=S_IFREG|0644, st_size=39931, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7d28000
read(8, "# subprocess - Subprocesses with"..., 4096) = 4096
read(8, "lso, the newlines attribute of t"..., 4096) = 4096
read(8, "code < 0:\n        print >>sys.st"..., 4096) = 4096
read(8, "alse does not exist on 2.2.0\ntry"..., 4096) = 4096
read(8, " p2cread\n        # c2pread    <-"..., 4096) = 4096
read(8, "table(self, handle):\n           "..., 4096) = 4096
read(8, "rrno using _sys_errlist (or siml"..., 4096) = 4096
read(8, " p2cwrite = None, None\n         "..., 4096) = 4096
write(2, "    ", 4)                     = 4
write(2, "self.pid = os.fork()\n", 21)  = 21
close(8)                                = 0
munmap(0xb7d28000, 4096)                = 0
write(2, "OSError", 7)                  = 7
write(2, ": ", 2)                       = 2
write(2, "[Errno 12] Cannot allocate memor"..., 33) = 33
write(2, "\n", 1)                       = 1
unlink("/var/run/sd-agent.pid")         = 0
close(3)                                = 0
munmap(0xb7e0d000, 4096)                = 0
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x589978}, {0xb89a60, [], SA_RESTORER, 0x589978}, 8) = 0
brk(0xa022000)                          = 0xa022000
exit_group(1)                           = ?

1
'파이프'나 파일 설명자 또는 이와 관련된 커널 리소스에서 빠져 나가나요?
Blauohr

확인 /var/log/messages또는 dmesg명령.
mark4o

이와 관련된 로그가 없습니다.
davidmytton

이것에 대한 해결책을 얻었습니까? 비슷한 증상이 있습니다. 여분의 메모리가 충분하지만 스왑을 추가하면 (일부 답변이 제안하는 것처럼) 문제가 사라집니다. 그 때와 지금 사이에 몇 달 동안 발견 한 것이 있는지 궁금했습니다. -- 감사!
dpb

동일한 문제가 발생하지만 해결책이 없습니다. 아이디어가 있습니까?

답변:


88

일반적인 규칙 (즉, 바닐라 커널)로, fork/ clone에 오류가 ENOMEM 구체적으로 발생 하기 때문에 하나의 하나님 께 정직이 메모리 부족 상태 ( dup_mm, dup_task_struct, alloc_pid, mpol_dup, mm_init등 까악 까악 우는 소리), 또는 때문에이 security_vm_enough_memory_mm당신을 실패 하면서 시행 오버 커밋 정책을 .

포크 시도시 포크에 실패한 프로세스의 vmsize를 확인한 다음 오버 커밋 정책 (숫자 연결)과 관련된 사용 가능한 메모리 (물리적 및 스왑)의 양과 비교합니다.

특정 경우 Virtuozzo에는 오버 커밋 시행에 대한 추가 검사 가 있습니다. 또한 컨테이너 내에서 스왑 및 오버 커밋 구성에 대한 제어 권한이 얼마나 있는지 잘 모르겠습니다. (적용 결과에 영향을 미치기 위해).

이제 실제로 앞으로 나아 가기 위해 두 가지 옵션남았습니다 .

  • 더 큰 인스턴스로 전환하거나
  • 스크립트의 메모리 공간 을 보다 효과적으로 제어하기 위해 코딩 노력을 기울입니다.

노트 그것은 당신이 아니라고 밝혀,하지만 당신은 amock을 실행으로 다른 사람이 같은 서버에 다른 인스턴스에 배치하면 코딩 노력이 수포에 대한 모든 수 있음.

메모리 현명한, 우리가 이미 알고있는 subprocess.Popen용도 fork/ clone 후드 아래에 당신이있어 호출 할 때마다 즉, 파이썬 많은 메모리로 다시 한 번 요청은 이미 먹고 그 다음에 순서대로 추가 MB, 모두의 수백 즉, 또는 exec같은 작은 10kB 실행 파일 . 바람직하지 않은 오버 커밋 정책의 경우 곧을 볼 수 있습니다.freepsENOMEM

fork이 상위 페이지 테이블 등 복사 문제가없는 대안 은 vforkposix_spawn입니다. 그러나 / subprocess.Popen에 대한 청크를 다시 작성하고 싶지 않다면 스크립트 시작 부분 (Python의 메모리 사용량이 최소 일 때)에 한 번만 사용하여 / / 및 다른 모든 항목 을 실행하는 쉘 스크립트생성하는 것이 좋습니다. 고리vforkposix_spawnsuprocess.Popenfreepssleep 스크립트와 병렬로 합니다. 스크립트의 출력을 폴링하거나 비동기 적으로 처리 할 다른 작업이있는 경우 별도의 스레드에서 동 기적으로 읽습니다. Python에서 데이터 크 런칭을 수행하되 분기는 종속 프로세스에 맡깁니다.

그러나이 , 특정 경우에 당신은 호출 건너 뛸 수 있습니다 psfree모두; 해당 정보는 직접procfs 액세스하든 기존 라이브러리 및 / 또는 패키지 를 통해 액세스하든 상관없이 에서 직접 Python에서 쉽게 사용할 수 있습니다 . 경우 psfree유일한 유틸리티를 실행 한 한, 당신은 할 수 페지 subprocess.Popen완전히 .

마지막으로, subprocess.Popen스크립트가 메모리를 누수하더라도 결국 벽에 부딪 힐 것입니다. 주시하고 메모리 누수를 확인하십시오 .


7
가비지 컬렉터가 한동안 실행되지 않은 경우 gc.collect()바로 직전 실행 이 subprocess.Popen도움이 된다는 것을 알았 습니다.
letmaik 2014-07-02

헬퍼 스크립트 전략을 처리하기 위해 데몬을 썼습니다. github.com/SeanHayes/errand-boy 클라이언트 중 한 명과 함께 프로덕션에서 사용하고 있으며 "메모리를 할당 할 수 없음"문제가 사라졌습니다.
Seán Hayes

/proc/fd/maps과도하게 할당 된 메모리가 실제로 문제인지 확인하기 위해 다음과 같은 간단한 진단 이 필요합니다.
Dima Tisnek

18

출력 살펴보기 free -m 실제로 사용할 수있는 스왑 메모리가없는 것 같습니다. Linux에서 스왑이 항상 필요에 따라 자동으로 제공되는지 확실하지 않지만 동일한 문제가 있었고 여기에있는 답변 중 어느 것도 실제로 도움이되지 않았습니다. 그러나 약간의 스왑 메모리를 추가하면 내 경우 문제가 해결되었으므로 동일한 문제에 직면 한 다른 사람들에게 도움이 될 수 있으므로 1GB 스왑을 추가하는 방법에 대한 답변을 게시합니다 (Ubuntu 12.04에서는 다른 배포판에서도 비슷하게 작동합니다).

먼저 활성화 된 스왑 메모리가 있는지 확인할 수 있습니다.

$sudo swapon -s

비어있는 경우 스왑이 활성화되지 않았 음을 의미합니다. 1GB 스왑을 추가하려면 :

$sudo dd if=/dev/zero of=/swapfile bs=1024 count=1024k
$sudo mkswap /swapfile
$sudo swapon /swapfile

에 다음 줄을 추가하여 fstab스왑을 영구적으로 만듭니다.

$sudo vim /etc/fstab

     /swapfile       none    swap    sw      0       0 

소스 및 자세한 정보는 여기 에서 찾을 수 있습니다 .


1
동일한 문제 또는 다른 문제가 해결 되었습니까?
Dima Tisnek

이것은 CentOS 6.4에서 나를 위해 해냈습니다. awstats를 설치하는 동안 오류가 발생했습니다. 감사합니다.
Ruslan Abuzant 2016

이렇게하면 코드를 실행할 수 있었지만 실제로 사용하는 라이브러리에있는 문제를 해결하지는 못했습니다.
philmaweb

1
내 문제를 고쳤습니다. 감사! +1
sscirrus

8

스왑은 이전에 제안 된 붉은 청어가 아닐 수 있습니다. 문제의 파이썬 프로세스가 얼마나 큽 ENOMEM니까?

커널 2.6에서는 /proc/sys/vm/swappiness커널이 얼마나 적극적으로 스왑으로 전환 할지를 제어하고 커널이 overcommit*윙크와 끄덕임으로 메모리를 얼마나 정확하게 할당 할 수 있는지 파일합니다. 페이스 북 관계 상태와 마찬가지로 복잡 합니다.

...하지만 스왑은 실제로 필요에 따라 사용할 수 있습니다 (웹 호스트에 따라) ...

그러나 free(1)서버 인스턴스에서 인식되는 스왑 공간이 없음을 보여주는 명령 의 출력에 따라 다릅니다. 이제 웹 호스트는이 주제에 대해 저보다 훨씬 더 많이 알고있을 수 있지만 제가 사용한 가상 RHEL / CentOS 시스템은 게스트 OS에서 사용 가능한 스왑을보고했습니다.

적응 레드햇 KB 문서 15252를 :

Red Hat Enterprise Linux 5 시스템은 익명 메모리와 시스템 V 공유 메모리의 합이 RAM 용량의 약 3/4 미만인 한 스왑 공간없이 잘 실행됩니다. 이하의 RAM이 4GB .... 시스템은 [하도록 권장] 스왑 공간 2GB의 최소.

/proc/sys/vm설정을 일반 CentOS 5.3 설치와 비교하십시오 . 스왑 파일을 추가합니다. 아래로 내려와 swappiness더 이상 살고 있는지 확인하십시오.


파이썬 프로세스의 크기를 확인하는 가장 좋은 방법은 무엇입니까? 추신?
davidmytton

같은 ps -o user,pid,vsz="Mem(Kb)" -o cmd $PYTHON_PID, 또는 상단 (1)을해야한다.
pilcrow 09.04.09

7

쉬운 수정을 위해 다음을 수행 할 수 있습니다.

echo 1 > /proc/sys/vm/overcommit_memory

시스템에 충분한 메모리가 있다고 확신하는 경우. Linux over commit heuristic을 참조하십시오 .


1
정말 고맙습니다! 이러한 쉬운 솔루션, 당신은 구원을 내 일)
igolkotek

5

고객 / 사용자가 clone()시스템 호출을 방해하는 일부 커널 모듈 또는 드라이버가로드되어 있거나 (아마도 LIDS와 같은 일부 모호한 보안 개선 사항) 또는 어떤 식 으로든 커널 데이터 구조 중 일부를 채우고 있다고 의심 합니다. fork()/ clone()작동에 필요 합니다 (프로세스 테이블, 페이지 테이블, 파일 설명자 테이블 등).

다음은 fork(2)매뉴얼 페이지 의 관련 부분입니다 .

오류
       EAGAIN fork ()는 부모의 페이지 테이블을 복사하기 위해 충분한 메모리를 할당 할 수없고
              아이.

       EAGAIN 호출자의 RLIMIT_NPROC 리소스 제한에 도달했기 때문에 새 프로세스를 생성 할 수 없습니다. 에
              이 제한을 초과하면 프로세스에 CAP_SYS_ADMIN 또는 CAP_SYS_RESOURCE 기능이 있어야합니다.

       ENOMEM fork ()는 메모리가 부족하기 때문에 필요한 커널 구조를 할당하지 못했습니다.

사용자가 스톡, 일반 커널로 부팅하고 최소한의 모듈 및 드라이버 세트 만로드 한 후이 작업을 시도하도록하는 것이 좋습니다 (애플리케이션 / 스크립트를 실행하는 데 필요한 최소한). 거기에서 해당 구성에서 작동한다고 가정하면 해당 구성과 문제를 나타내는 구성 사이에서 이진 검색을 수행 할 수 있습니다. 이것은 표준 sysadmin 문제 해결 101입니다.

귀하의 관련 라인은 다음 strace과 같습니다.

clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7f12708) = -1 ENOMEM (Cannot allocate memory)

... 다른 사람들이 스왑 및 메모리 가용성에 대해 이야기 한 것을 알고 있습니다 (아이러니하게도 RAM 디스크에 있더라도 최소한 작은 스왑 파티션을 설정하는 것이 좋습니다. 사용 가능한 스왑이 거의없는 경우 (예외 처리 경로)보다 훨씬 더 광범위하게 사용할 수있는 스왑이 있습니다.

그러나 나는 이것이 여전히 붉은 청어라고 생각합니다.

free캐시와 버퍼에서 사용중인 0 (ZERO) 메모리를보고 한다는 사실 은 매우 충격적입니다. 나는 free출력 ... 그리고 아마도 당신의 응용 프로그램 문제가 어떤 식 으로든 메모리 할당을 방해하는 독점적 커널 모듈로 인해 발생한다고 생각합니다.

fork () / clone ()의 man 페이지에 따르면 fork () 시스템 호출은 호출로 인해 리소스 제한 위반 (RLIMIT_NPROC)이 발생하는 경우 EAGAIN을 반환해야하지만 EAGAIN이 반환되는지 여부는 표시되지 않습니다. 다른 RLIMIT * 위반에 의해. 어떤 경우에도 대상 / 호스트에 이상한 Vormetric 또는 기타 보안 설정이있는 경우 (또는 프로세스가 이상한 SELinux 정책에서 실행 중이더라도)이 -ENOMEM 오류가 발생할 수 있습니다.

평범한 Linux / UNIX 문제는 아닐 것입니다. 비표준적인 일이 벌어지고 있습니다.


1
서버는 가상화를 위해 Virtuozzo를 사용하는 미디어 템플릿 (dv) 기반에서 실행됩니다.
davidmytton

Virtuozzo 메시지 보드 및 버그 추적 시스템을 검색하고 아마도 Virtuozzo 하위 시스템 자체에 대한 업그레이드를 찾으십시오.
Jim Dennis 2011

2

다음을 사용해 보셨습니까?

(status,output) = commands.getstatusoutput("ps aux")

나는 이것이 나에게 똑같은 문제를 해결했다고 생각했습니다. 하지만 내 프로세스는 스폰에 실패하는 대신 결국 죽게되었고, 이는 더 나쁩니다 ..

몇 가지 테스트 후 나는 이것이 이전 버전의 파이썬에서만 발생한다는 것을 발견했습니다 .2.6.5에서는 발생하지만 2.7.2에서는 발생하지 않습니다.

내 검색으로 python-close_fds-issue 이지만 closed_fds 설정을 해제해도 문제가 해결되지 않았습니다. 여전히 읽을만한 가치가 있습니다.

파이썬이 파일 설명자를 주시하는 것만으로도 유출되고 있음을 발견했습니다.

watch "ls /proc/$PYTHONPID/fd | wc -l"

여러분처럼 명령의 출력을 캡처하고 OOM 오류를 피하고 싶지만 사람들이 버그가 적은 Python 버전을 사용하는 것이 유일한 방법 인 것 같습니다. 이상적이지 않습니다 ...


0

munmap (0xb7d28000, 4096) = 0
write (2, "OSError", 7) = 7

다음과 같은 조잡한 코드를 보았습니다.

serrno = errno;
some_Syscall(...)
if (serrno != errno)
/* sound alarm: CATROSTOPHIC ERROR !!! */

이것이 파이썬 코드에서 일어나는 일인지 확인해야합니다. Errno는 진행중인 시스템 호출이 실패한 경우에만 유효합니다.

추가하기 위해 편집 :

이 과정이 얼마나 오래 지속되는지 말하지 않습니다. 가능한 메모리 소비자

  • 분기 된 프로세스
  • 사용하지 않는 데이터 구조
  • 공유 라이브러리
  • 메모리 매핑 파일

2
예, 그러나 OP의 strace에서 clone ()에서 발생한 첫 번째 syscall 실패가보고 된대로 ENOMEM임을 알 수 있습니다. 이 오류는 C- 라이브러리 errno가 도중에 여러 번 재설정 되더라도 추적 생성을 통해 비틀 거리는 파이썬의 메모리 부족과 함께 보존됩니다 .
pilcrow

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.