생성 후 Node.js가 ENOMEM 오류를 포착합니다.


82

내 Node.js 스크립트는 spawn을 사용할 때 throw 된 ENOMEM (메모리 부족) errnoException으로 인해 충돌 합니다 .

오류:

child_process.js:935
  throw errnoException(process._errno, 'spawn');
        ^

Error: spawn ENOMEM
  at errnoException (child_process.js:988:11)
  at ChildProcess.spawn (child_process.js:935:11)
  at Object.exports.spawn (child_process.js:723:9)
  at module.exports ([...]/node_modules/zbarimg/index.js:19:23)

이미 errorexit이벤트에 대한 리스너를 사용 하고 있지만이 오류가 발생하는 경우 해고되지 않습니다.

내 코드 :

zbarimg = process.spawn('zbarimg', [photo, '-q']);
zbarimg.on('error', function(err) { ... });
zbarimg.on('close', function(code) { ... }); 

전체 소스 코드를 사용할 수 있습니다 .

스크립트 충돌을 방지하기 위해 할 수있는 일이 있습니까? 던져진 ENOMEM 오류를 어떻게 잡나요?

감사!


문제를 복제하는 데 사용할 수있는 예제 이미지가 있습니까?
mscdex

서버의 메모리가 부족하여 특정 이미지로 재현 할 수 없을 때 발생합니다. / - : 그 시험에 열심히하게
TOBI

error핸들러 안에서 무엇을하고 있습니까?
mscdex

1
이 문제에 대한 해결책을 찾았습니까?
sffc

2
나는 이것이 fork()(기본 syscall) 사용의 근본적인 결함이라고 생각합니다 . github.com/nodejs/node/issues/25382
ZachB를

답변:


201

나는 같은 문제가 있었고 그 결과 내 시스템 에는 스왑 공간이 활성화되지 않았습니다 . 다음 명령을 실행하여이 경우인지 확인하십시오 free -m.

vagrant@vagrant-ubuntu-trusty-64:~$ free -m
             total       used       free     shared    buffers     cached
Mem:          2002        233       1769          0         24         91
-/+ buffers/cache:        116       1885
Swap:            0          0          0

맨 아래 행을 보면 총 0 바이트 스왑 메모리가 있음을 알 수 있습니다. 안좋다. 노드는 꽤 많은 메모리를 고갈시킬 수 있으며 메모리가 부족할 때 사용 가능한 스왑 공간이 없으면 오류가 발생합니다.

스왑 파일을 추가하는 방법은 운영 체제와 배포판에 따라 다르지만 나처럼 Ubuntu를 실행하는 경우 다음 지침에 따라 스왑 파일을 추가 할 수 있습니다 .

  1. sudo fallocate -l 4G /swapfile 4GB 스왑 파일 만들기
  2. sudo chmod 600 /swapfile 루트에 대한 액세스를 제한하여 스왑 파일 보안
  3. sudo mkswap /swapfile 파일을 스왑 공간으로 표시
  4. sudo swapon /swapfile 스왑 활성화
  5. echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab재부팅시 스왑 파일 유지 (팁, bman 감사합니다 !)

14
이 답변을 읽는 미래의 모든 사람을위한 메모입니다. Swapfile은 재부팅시 지속되지 않습니다. 영구적으로 만들려면 / etc / fstab 파일을 편집하고 끝에 줄을 추가해야합니다. / swapfile none swap sw 0 0
bman

내 어리석은 VM 2 기가 더 많은 램을주는 것만으로 위의 문제가 해결되었습니다.
Thomson Comer

2
프로덕션 서버에서 이것이 좋은 생각입니까? 내 이해는 OS가 스왑 메모리를 사용하기 시작하면 성능이 급격히 저하 될 수 있으므로 애플리케이션의 요구 사항을 처리 할 수있는 충분한 RAM으로 서버의 크기를 조정하고 메모리 누수를 적극적으로 찾는 것이 좋습니다.
josh

2
@josh, RAM이 부족하면 두 가지 중 하나가 발생합니다. 메모리가 스왑 파일로 페이징되거나 추가 메모리에 대한 요청이 예기치 않은 결과로 실패합니다. 예, 스왑 파일을 사용하면 성능이 저하 될 수 있지만, 특히 프로덕션 환경에서 다른 옵션보다 더 많이 사용하겠습니다 .
Kaivosukeltaja

메모리를 두 배로 늘리지 않았고 크기를 조정해야합니까? 어떻게해야합니까?
Jack

4

AWS Lambda에서이 문제가 발생하면 함수에 할당 된 메모리를 늘리는 것을 고려해야합니다.


2

다음 명령을 사용하여 메모리 노드 사용량을 변경할 수 있습니다. node ----max-old-space-size=1024 yourscript.js

--max-old-space-size = 1024는 1 기가의 메모리를 할당합니다.

기본적으로 노드는 512MB의 램을 사용하지만 플랫폼에 따라 필요에 따라 가비지 수집이 시작되도록 더 많거나 적은 할당이 필요할 수 있습니다.

플랫폼에 사용 가능한 RAM이 500MB 미만인 경우 메모리 사용량을 --max-old-space-size = 256으로 낮게 설정해보십시오.


1

나는 같은 문제가 있었고 try / catch로 수정했습니다.

try {
  zbarimg = process.spawn('zbarimg', [photo, '-q']);
} catch (err) {
  console.log(err);
}
zbarimg.on('error', function(err) { ... });
zbarimg.on('close', function(code) { ... }); 

0

노드 서버를 비활성화하고 다시 활성화하여 문제를 해결했습니다.


-5

호출 된 프로세스에서 출력을 플러시해야합니다!

파이썬 예제는 다음과 같습니다.

import sys
...
sys.stdout.flush()

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