Node.js bắt lỗi ENOMEM sau khi xuất hiện


82

Tập lệnh Node.js của tôi gặp sự cố do lỗi ENOMEM (Hết bộ nhớ) bị ném khi sử dụng spawn .

Lỗi:

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)

Tôi đã sử dụng người nghe cho sự kiện errorexitsự kiện, nhưng không phải người trong số họ bị đuổi trong trường hợp xảy ra lỗi này.

Mã của tôi:

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

Mã nguồn đầy đủ có sẵn .

Tôi có thể làm gì để ngăn tập lệnh gặp sự cố không? Làm cách nào để bắt lỗi ENOMEM đã bị ném ra?

Cảm ơn!


Bạn có một hình ảnh ví dụ có thể được sử dụng để tái tạo sự cố không?
mscdex

Nó xảy ra khi máy chủ hết bộ nhớ và không thể tái tạo bằng một hình ảnh cụ thể. Điều đó làm cho nó khó khăn để kiểm tra: - /
tobi

Bạn đang làm gì bên trong errortrình xử lý?
mscdex

1
Bạn đã tìm ra giải pháp cho vấn đề này chưa?
sffc

2
Tôi nghĩ rằng đây là một lỗ hổng cơ bản khi sử dụng fork()(syscall cơ bản). Xem github.com/nodejs/node/issues/25382
ZachB

Câu trả lời:


201

Tôi đã gặp vấn đề tương tự và hóa ra, hệ thống của tôi đã không được kích hoạt không gian hoán đổi . Kiểm tra xem có phải trường hợp này không bằng cách chạy lệnh 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

Nhìn vào hàng dưới cùng, chúng ta có thể thấy chúng ta có tổng cộng 0 byte bộ nhớ hoán đổi. Không tốt. Node có thể bị đói bộ nhớ khá lớn và nếu không có không gian hoán đổi khi bộ nhớ hết, lỗi sẽ xảy ra.

Phương pháp thêm tệp hoán đổi khác nhau giữa các hệ điều hành và bản phân phối, nhưng nếu bạn đang chạy Ubuntu như tôi, bạn có thể làm theo hướng dẫn sau để thêm tệp hoán đổi :

  1. sudo fallocate -l 4G /swapfile Tạo một tệp hoán đổi 4 gigabyte
  2. sudo chmod 600 /swapfile Bảo mật swapfile bằng cách hạn chế quyền truy cập vào root
  3. sudo mkswap /swapfile Đánh dấu tệp là không gian hoán đổi
  4. sudo swapon /swapfile Cho phép hoán đổi
  5. echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstabKiên trì swapfile sau khi khởi động lại (cảm ơn vì mẹo, bman !)

14
Chỉ là một lưu ý cho bất kỳ ai trong tương lai đang đọc câu trả lời này. Swapfile không liên tục khi khởi động lại. Để làm cho nó hoạt động liên tục, bạn cần chỉnh sửa tệp / etc / fstab và thêm một dòng ở cuối: / swapfile none swap sw 0 0
bman

Chỉ cần cung cấp cho VM ngu ngốc của tôi thêm 2 hợp đồng ram đã giải quyết được vấn đề ở trên của tôi.
Thomson Comer

2
Đây có phải là một ý tưởng hay trên máy chủ sản xuất không? Tôi hiểu là khi hệ điều hành bắt đầu sử dụng bộ nhớ hoán đổi, hiệu suất có thể giảm mạnh, vì vậy tốt hơn hết bạn nên kích thước máy chủ của mình có đủ RAM để xử lý các nhu cầu của ứng dụng và tích cực tìm kiếm các chỗ rò rỉ bộ nhớ.
josh

2
@josh, khi RAM hết một trong hai điều sẽ xảy ra - hoặc bộ nhớ sẽ được phân trang thành tệp hoán đổi hoặc bất kỳ yêu cầu nào về bộ nhớ bổ sung sẽ không thành công với kết quả không mong muốn. Có, hiệu suất có thể giảm khi một tệp hoán đổi được sử dụng nhưng tôi sẽ thực hiện điều đó bất kỳ ngày nào thay vì tùy chọn khác, đặc biệt là trong sản xuất.
Kaivosukeltaja

Tôi đã không tăng gấp đôi bộ nhớ và cần thay đổi kích thước? Làm thế nào để tôi làm điều này?
Jack

4

Nếu bạn từng gặp sự cố này trong AWS Lambda, bạn nên cân nhắc việc tăng bộ nhớ được cấp phát cho hàm.


2

Bạn có thể thử thay đổi số lượng nút bộ nhớ sử dụng bằng lệnh này: node ----max-old-space-size=1024 yourscript.js

--max-old-space-size = 1024 sẽ cấp phát 1 gig bộ nhớ.

Theo mặc định, nút sẽ sử dụng 512 mb ram nhưng tùy thuộc vào nền tảng của bạn, bạn có thể cần phải phân bổ nhiều hơn hoặc ít hơn để bộ sưu tập rác hoạt động khi bạn cần.

Nếu nền tảng của bạn có sẵn ít hơn 500 mb ram thì hãy thử đặt mức sử dụng bộ nhớ thấp hơn thành --max-old-space-size = 256.


1

Tôi đã gặp sự cố tương tự và đã khắc phục bằng 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

Tôi đã khắc phục sự cố bằng cách vô hiệu hóa và bật lại Máy chủ Node của mình.


-5

Bạn phải xóa các đầu ra khỏi quá trình được gọi!

Một ví dụ về python trông như thế này:

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

nó không phải là một con trăn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.