2011-03-15 5 views
4

일부 생물 정보학 작업을하고 있습니다. 파이썬 스크립트를 가지고있어서 값 비싼 프로세스를 수행하는 프로그램을 호출합니다 (시퀀스 정렬은 많은 계산 능력과 메모리를 사용합니다). 나는 subprocess.Popen을 사용하여 그것을 부른다. 테스트 케이스에서 실행하면 완료되고 정상적으로 완료됩니다. 그러나 여러 파일 세트에 대해이 작업을 여러 번 수행해야하는 전체 파일에서 실행하면 파일이 종료됩니다. 서브 프로세스를 사용한 파이썬 메모리 할당 오류

OSError: [Errno 12] Cannot allocate memory 

나는 비슷한 문제로 몇 가지 링크를 hereherehere을 찾았지만, 나는 그들이 내 경우에 적용하는 것이 확실하지 않다 : 하위 프로세스가 발생합니다.

기본적으로 시퀀스 정렬 기는 51000M의 메모리를 요청하려고 시도합니다. 그것은 항상 그렇게 많이 사용하지는 않지만, 그렇게 할 수도 있습니다. 전체 입력을로드하고 처리하면 그만큼 사용할 수 없습니다. 그러나 요청할 때 사용량을 줄이거 나 사용량을 줄이면 실행 중에도 여전히 동일한 오류가 발생합니다. 나는 또한 shell = True와 같은 것을 실행 해 보았습니다.

이것은 며칠 동안 나를 괴롭 히고 있습니다. 어떤 도움을 주셔서 감사합니다.

편집 : 역 추적을 확장 :

File "..../python2.6/subprocess.py", line 1037, in _execute_child 
    self.pid=os.fork() 
OSError: [Errno 12] Cannot allocate memory 

오류가 발생합니다.

Edit2가 : 64 비트 우분투 10.4

+0

에 무슨 일이 일어나고 있는지 설명 할 수있는 주제에 대한 여러 스택 오버플로 게시물을 표시합니다 명령 줄에서? 여러 인스턴스를 백그라운드로 설정하여 실행할 수 있습니까 (명령을'&'로 끝내기)? 프로그램의 컴퓨터 자원 사용에 대한 통계를 얻기 위해'time -v foo ... '를 실행하는 것은 어떻습니까? – Apalala

답변

0

에 파이썬 2.6.4에서 실행하면 내가 64 비트 OS에서 64 비트 파이썬을 실행하는 것입니다.

32 비트를 사용하면 OS가 시작하기 전에 실제로는 3GB의 RAM 만 얻을 수 있습니다.

편집

http://docs.python.org/library/mmap.html

: 아 64 비트에있어 .. 아마도 원인은 아웃 실행중인 것을

또 다른 대안은 파일을 열 메모리 매핑 된 파일 사용할 수 있습니다 RAM + 스왑 .. 스왑 어쩌면 양을 늘리는 것일 수도 있습니다.

+0

양쪽에서 64 비트를 실행 중입니다. 메모리 매핑 파일과 일반 파일을 비교하면 어떤 점이 유리합니까? – jmerkin

+0

잘 장점 중 하나는 임의 또는 순차적 액세스를 위해 최적화하도록 OS에 지시 할 수 있으며 RAM보다 큰 파일을 열어 청크 할 수 있다는 것입니다. – matiu

+0

메모리 매핑 된 파일의 단점은 컴퓨터가 예기치 않게 다운되면 매우 손상 될 수 있다는 것입니다. – matiu

0

이 모듈은 Python 또는 subprocess 모듈과 아무런 관련이 없습니다. subprocess.Popen은 운영 체제에서 수신하는 오류를보고하는 것일뿐입니다. (당신은 방법에 의해, 어떤 운영 체제를 사용하고 있습니까?) man 2 fork에서 리눅스 :

ENOMEM fork() failed to allocate the necessary kernel structures 
      because memory is tight. 

당신은 subprocess.Popen 여러 번 호출하고 있습니까? 그렇다면 당신이 할 수있는 최선의 방법은 프로세스의 이전 호출이 종료되고 다음 호출 전에 확보되는지 확인하는 것입니다.

+0

나는 여러 번 그것을 연속적으로 부른다. 나는 stdout을 원하기 때문에 거기에 subprocess.communicate()를 던진다. – jmerkin

+1

또한 메모리가 부족한 경우 리눅스가 스왑 파일을 사용하지 않는 이유는 무엇입니까? (컴퓨터가 공유 리소스이며 64g의 RAM을 가지고있어서 스왑 공간이 정의되지 않았다고 생각합니까?) – jmerkin

+0

@jmerkin, 'swapon -s'를 사용하여 스왑이 구성되었는지 확인하고 사용 가능한 물리 메모리와 스왑 공간의 양을 알려면'free'를 사용하십시오. 스왑이없는 경우 사용 가능한 가상 메모리를 늘리는 한 가지 방법은 스왑을 구성하는 것입니다. 또한, @ Constantin Tenzin의 질문에 답하는 것이 좋습니다. 실제로 하위 프로세스 (stdout/stderr)의 결과를 사용하고 있습니까? 그렇다면 결과가 큽니까? 그렇다면 파이썬 프로세스가 사용 가능한 모든 메모리를 소비하지 않도록하기 위해 무엇을하고 있습니까? – rlibby

0

하위 프로세스를 사용합니까? PIPE? 문제가 생겼을 때 문제가 있었고 문제를 읽었습니다. 임시 파일은 일반적으로 문제를 해결합니다.

+0

나는 두 가지 방법을 시도했다. 난 직접 파일뿐만 아니라 subprocess.PIPE : a = subprocess.Popen ('foo> bar', shell = True, stderr = subprocess.PIPE); a.wait()) a = subprocess.Popen (foo, stdout = subprocess.PIPE, stderr = subprocess.PIPE) f_out.write (a.communicate() [0]) 그리고이 오류도 나에게 줬다. Stderr는 꽤 무시할 만하다. 프로그램의 진행 상황과 관련해서는 몇 줄 밖에 없으므로 그다지 중요하지 않아야한다. – jmerkin

4

나는 OP를 정말 유감으로 생각한다. 6 년 후 아무도 이것이 유닉스에서 매우 흔한 문제이며 파이썬이나 생물 정보학과는 아무런 관련이 없다고 언급했다. os.fork()를 호출하면 exec()를 수행하기 전에 부모 프로세스의 메모리가 일시적으로 두 배가됩니다 (부모 프로세스의 메모리가 자식 프로세스에서 사용 가능해야합니다).이 메모리가 항상 실제로 복사되는 것은 아니지만 시스템에 복사 할 수있는 충분한 메모리가 있어야하므로 부모 프로세스가 시스템 메모리의 절반 이상을 사용하고 "wc -l" ", 당신은 메모리 오류가 발생합니다.

해결 방법은 메모리 사용량이 적은 동안 posix_spawn을 사용하거나 스크립트 시작 부분에 모든 하위 프로세스를 생성 한 다음 부모 프로세스가 메모리 집약적 인 작업을 수행 한 후에 나중에 사용하는 것입니다.

keyworks "os.fork"와 "메모리"를 사용하는 구글 검색, 추가로 독립형 모드에서 하위 프로세스 프로그램을 실행할 수 있습니다 :