복붙노트

[PYTHON] How to avoid [Errno 12] 서브 프로세스 모듈 사용으로 인한 메모리 오류를 할당 할 수 없습니다.

PYTHON

How to avoid [Errno 12] 서브 프로세스 모듈 사용으로 인한 메모리 오류를 할당 할 수 없습니다.

완벽한 작동 테스트 케이스

물론 로컬 및 원격 컴퓨터의 메모리에 따라 배열 크기가 달라집니다.

z1 = numpy.random.rand(300000000,2);
for i in range(1000):
  print('*******************************************\n'); 
  direct_output = subprocess.check_output('ssh blah@blah "ls /"', shell=True);
  direct_output = 'a'*1200000; 
  a2 = direct_output*10;
  print(len(direct_output));

현재 사용 사례

내 유스 케이스에 도움이되는 경우에는 다음과 같습니다.

db 쿼리를 실행 한 다음 결과 테이블을 원격 시스템에 저장합니다. 그런 다음 네트워크를 통해 전송하고 분석을 수행하려고합니다. 지금까지 나는 파이썬에서 다음과 같은 것을 해왔다.

#run a bunch of queries before hand with the results in remote files

....
counter = 0
mergedDataFrame = None
while NotDone:
  output = subprocess.check_output('ssh blah@blah cat /data/file%08d'%(counter))
  data = pandas.read_csv(...)
  #do lots of analysis, append, merge, numpy stuff etc...
  mergedDataFrame = pandas.merge(...)
  counter += 1

어떤 시점에서 나는 check_output 명령에서 다음 오류를 수신합니다 : [Errno 12] 메모리를 할당 할 수 없습니다

배경

아래의 질문들 덕분에 나는 틀린 것이 무엇인지 생각하고있다. 게시 된 솔루션은 여러 가지이며 솔루션 중 어떤 것이 [Errno 12] fork / clone을 사용하여 하위 프로세스 구현과 관련된 메모리 오류를 할당 할 수 없는지 확인하려고합니다.

파이썬 subprocess.Popen "OSError : [Errno 12] 메모리를 할당 할 수 없습니다"이것은 기본 진단을 제공하고 별도의 스크립트 등을 생성하는 것과 같은 몇 가지 해결 방법을 제안합니다 ...

파이썬 포크 및 메모리 할당 오류 이해하기 fork / clone의 서브 프로세스 제한을 우회하여 자식 프로세스를 생성하고 메모리를 복사하는 것을 우회하기 위해 rfoo를 사용하도록 제안한다. 이것은 클라이언트 - 서버 모델을 의미하는 것으로 보인다.

파이썬을 사용하는 SSH에 대한 가장 간단한 방법은 무엇입니까? ,하지만 난 메모리 제한과 포크 / 복제 구현으로 인해 하위 프로세스를 사용할 수 없다는 추가적인 제약이 있습니까? 해결책은 paramiko 또는 그 위에 구축 된 것을 사용하는 것이고, 다른 것들은 하위 프로세스를 제안하는 것입니다 (필자의 경우에는 작동하지 않습니다).

다른 비슷한 질문이 있었지만, 파일 설명자가 범인 (이 경우에는 그렇지 않습니다)에 대해 이야기하고, 시스템에 RAM을 추가하여 (저는이 작업을 수행 할 수 없습니다) x64 (이미 x64)로 업그레이드했습니다. ENOMEM 문제를 암시하는 사람들도 있습니다. Subprocess.Popen (제 경우에는 check_output)이 프로세스를 적절하게 정리하지 못하고 있지만 S. Lott와 다른 사람들은 서브 프로세스 코드 자체가 제대로 정리되고 있음에 동의합니다.

나는 github https://github.com/paramiko/paramiko/search?q=Popen&type=Code에서 소스 코드를 검색했으며 proxy.py 파일에서 subprocess를 사용하는 것처럼 보입니다.

실제 질문

이것은 궁극적으로 paramiko가 위에서 설명한 Popen 솔루션을 사용한다는 것을 의미합니까? 파이썬 메모리 풋 프린트가 커지고 복제 / 포크 구현으로 인해 Popen 호출이 반복 될 때 문제가 발생합니까?

paramiko가 작동하지 않는다면 클라이언트 측 솔루션으로 내가 찾고있는 것을 할 수있는 또 다른 방법이 있습니까? 아니면 클라이언트 / 서버 / 소켓 솔루션이 필요합니까? rfoo, tornado, zeromq 중 어떤 것이 HTTP 전송이 가능합니까?

노트 나는 64 비트 리눅스 8 기가 바이트 메인 메모리를 실행 중입니다. 나는 더 많은 RAM을 구입할 수있는 옵션을 추구하고 싶지 않습니다.

해결법

  1. ==============================

    1.메모리가 부족한 경우 스왑 메모리를 늘려야 할 수 있습니다. 또는 스왑을 전혀 사용할 수 없습니다. Ubuntu에서는 (다른 배포판에서도 잘 작동 할 것입니다) 다음과 같이 스왑을 확인할 수 있습니다 :

    메모리가 부족한 경우 스왑 메모리를 늘려야 할 수 있습니다. 또는 스왑을 전혀 사용할 수 없습니다. Ubuntu에서는 (다른 배포판에서도 잘 작동 할 것입니다) 다음과 같이 스왑을 확인할 수 있습니다 :

    $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 
    

    근원 및 더 많은 정보는 여기에서 찾아 낼 수있다.

  2. ==============================

    2.메모리가 부족한 경우, 하위 프로세스가 동시에 너무 많은 메모리를 읽으려고하기 때문일 수 있습니다. 해결책은 로컬 파일로의 리디렉션을 사용하는 것 이외에, 한 번에 조금씩 읽을 수있는 stdin / stdout 쌍과 함께 popen과 같은 기능을 사용하는 것입니다.

    메모리가 부족한 경우, 하위 프로세스가 동시에 너무 많은 메모리를 읽으려고하기 때문일 수 있습니다. 해결책은 로컬 파일로의 리디렉션을 사용하는 것 이외에, 한 번에 조금씩 읽을 수있는 stdin / stdout 쌍과 함께 popen과 같은 기능을 사용하는 것입니다.

  3. ==============================

    3.이 작업을 수행해야합니다.

    이 작업을 수행해야합니다.

    http://docs.python.org/3.3/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3

    이렇게하면 한 번에 전체 내용 대신 선이나 블록을 읽을 수 있습니다.

  4. from https://stackoverflow.com/questions/20111242/how-to-avoid-errno-12-cannot-allocate-memory-errors-caused-by-using-subprocess by cc-by-sa and MIT license