Node.js heap hết bộ nhớ


245

Hôm nay tôi đã chạy tập lệnh của mình để lập chỉ mục hệ thống tập tin để làm mới chỉ mục tập tin RAID và sau 4h, nó bị lỗi với lỗi sau:

[md5:]  241613/241627 97.5%  
[md5:]  241614/241627 97.5%  
[md5:]  241625/241627 98.1%
Creating missing list... (79570 files missing)
Creating new files list... (241627 new files)

<--- Last few GCs --->

11629672 ms: Mark-sweep 1174.6 (1426.5) -> 1172.4 (1418.3) MB, 659.9 / 0 ms [allocation failure] [GC in old space requested].
11630371 ms: Mark-sweep 1172.4 (1418.3) -> 1172.4 (1411.3) MB, 698.9 / 0 ms [allocation failure] [GC in old space requested].
11631105 ms: Mark-sweep 1172.4 (1411.3) -> 1172.4 (1389.3) MB, 733.5 / 0 ms [last resort gc].
11631778 ms: Mark-sweep 1172.4 (1389.3) -> 1172.4 (1368.3) MB, 673.6 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3d1d329c9e59 <JS Object>
1: SparseJoinWithSeparatorJS(aka SparseJoinWithSeparatorJS) [native array.js:~84] [pc=0x3629ef689ad0] (this=0x3d1d32904189 <undefined>,w=0x2b690ce91071 <JS Array[241627]>,L=241627,M=0x3d1d329b4a11 <JS Function ConvertToString (SharedFunctionInfo 0x3d1d3294ef79)>,N=0x7c953bf4d49 <String[4]\: ,\n  >)
2: Join(aka Join) [native array.js:143] [pc=0x3629ef616696] (this=0x3d1d32904189 <undefin...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/bin/node]
 2: 0xe2c5fc [/usr/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/bin/node]
 6: v8::internal::Runtime_SparseJoinWithSeparator(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
 7: 0x3629ef50961b

Máy chủ được trang bị RAM 16gb và trao đổi SSD 24gb. Tôi rất nghi ngờ kịch bản của tôi vượt quá 36gb bộ nhớ. Ít nhất là không nên

Script tạo chỉ mục các tệp được lưu trữ dưới dạng Mảng đối tượng với siêu dữ liệu tệp (ngày sửa đổi, quyền, v.v., không có dữ liệu lớn)

Đây là mã tập lệnh đầy đủ: http://pastebin.com/mjaD76c3

Tôi đã từng gặp phải các vấn đề về nút lạ trong quá khứ với kịch bản này, điều khiến tôi bị ép buộc. phân chia chỉ mục thành nhiều tệp khi nút bị trục trặc khi làm việc trên các tệp lớn như Chuỗi. Có cách nào để cải thiện việc quản lý bộ nhớ của nodejs với các bộ dữ liệu khổng lồ không?

Câu trả lời:


313

Nếu tôi nhớ chính xác, có giới hạn tiêu chuẩn nghiêm ngặt cho việc sử dụng bộ nhớ trong V8 khoảng 1,7 GB, nếu bạn không tăng thủ công.

Trong một trong những sản phẩm của chúng tôi, chúng tôi đã theo giải pháp này trong kịch bản triển khai của mình:

 node --max-old-space-size=4096 yourFile.js

Cũng sẽ có một lệnh không gian mới nhưng như tôi đã đọc ở đây: a-tour-of-v8-rác-bộ sưu tập , không gian mới chỉ thu thập dữ liệu ngắn hạn mới được tạo và không gian cũ chứa tất cả các cấu trúc dữ liệu được tham chiếu nên có trong trường hợp của bạn là lựa chọn tốt nhất.


Theo cách tương tự, cấu hình này dành cho nodejs độc lập trên khung. @ Simer
Felix

Tôi đang phát triển với góc 4 và gặp vấn đề tương tự, tệp yourFile.js của bạn nên dùng gì cho ứng dụng góc?
Vikram

@VikramSingh bạn đang sử dụng ng servehay bạn phân phối kết quả của ng buildthư mục / dist bởi một máy chủ web khác như express? Nhưng nếu dự án Angular của bạn đang sử dụng nhiều hơn Bộ nhớ 1.7GB tiêu chuẩn thì bạn có thể gặp vấn đề về kiến ​​trúc trong ứng dụng của mình không? Có vẻ như bạn đang sử dụng env phát triển với nmp start có lẽ đây là một giải pháp cho nó github.com/mgechev/angular-seed/issues/2063
Felix

Tôi đang sử dụng ng build với angi cli và aot (thư mục dist)
Vikram

2
chỉ mục, tệp js @Techdive mà bạn sử dụng để khởi động máy chủ
Basit

77

Chỉ trong trường hợp bất kỳ ai chạy vào đây trong một môi trường nơi họ không thể đặt thuộc tính nút trực tiếp (trong trường hợp của tôi là công cụ xây dựng):

NODE_OPTIONS="--max-old-space-size=4096" node ...

Bạn có thể đặt các tùy chọn nút bằng biến môi trường nếu bạn không thể truyền chúng trên dòng lệnh.


Bạn có thể giải thích ý của bạn không, khi bạn nói "... thiết lập các tùy chọn nút bằng biến môi trường .."?
Keselme

6
@Keselme Một biến môi trường là một biến đã được đặt trên máy chủ mà tất cả các quy trình có thể đọc dữ liệu từ đó. Mở một thiết bị đầu cuối SSH đến máy chủ của bạn và gõ: MY_VAR = xin chào, sau đó gõ: echo $ MY_VAR. Bạn sẽ thấy nó in "xin chào" trong thiết bị đầu cuối. Bạn vừa đặt một biến môi trường và đọc lại.
Rob Evans

đã làm việc trên Ubuntu 18.04, chỉ cần thêm lệnh xuất vào tệp bashrc của tôi
Rahal K Biếnka

76

Nếu bạn muốn tăng mức sử dụng bộ nhớ của nút trên toàn cầu - không chỉ tập lệnh đơn, bạn có thể xuất biến môi trường, như sau:
export NODE_OPTIONS=--max_old_space_size=4096

Sau đó, bạn không cần phải chơi với các tệp khi chạy các bản dựng như thế nào npm run build.


1
Để thuận tiện hơn, hãy thêm vào hồ sơ bash_profile hoặc zsh.
Tropicalrambler

24

Tôi gặp phải vấn đề này khi cố gắng gỡ lỗi với VSCode, vì vậy chỉ muốn thêm đây là cách bạn có thể thêm đối số vào thiết lập gỡ lỗi của mình.

Bạn có thể thêm nó vào thuộc runtimeArgstính của cấu hình của bạn trong launch.json.

Xem ví dụ dưới đây.

{
"version": "0.2.0",
"configurations": [{
        "type": "node",
        "request": "launch",
        "name": "Launch Program",
        "program": "${workspaceRoot}\\server.js"
    },
    {
        "type": "node",
        "request": "launch",
        "name": "Launch Training Script",
        "program": "${workspaceRoot}\\training-script.js",
        "runtimeArgs": [
            "--max-old-space-size=4096"
        ]
    }
]}

21

Dưới đây là một số giá trị cờ để thêm một số thông tin bổ sung về cách cho phép thêm bộ nhớ khi bạn khởi động máy chủ nút.

1GB - 8GB

#increase to 1gb
node --max-old-space-size=1024 index.js

#increase to 2gb
node --max-old-space-size=2048 index.js 

#increase to 3gb
node --max-old-space-size=3072 index.js

#increase to 4gb
node --max-old-space-size=4096 index.js

#increase to 5gb
node --max-old-space-size=5120 index.js

#increase to 6gb
node --max-old-space-size=6144 index.js

#increase to 7gb
node --max-old-space-size=7168 index.js

#increase to 8gb 
node --max-old-space-size=8192 index.js 

người ta có thể tiếp tục tăng nó trong quyền hạn của 2 không? Có nên đặt nó lớn hơn bộ nhớ hệ thống? nếu không phải là một bộ nhớ hệ thống tốt với tỷ lệ kích thước không gian tối đa cũ?
Harry Moreno

3
@HarryMoreno Bạn thực sự có thể đặt bất kỳ giá trị số nào bạn muốn. Không phải có sức mạnh của 2. Mặc dù không chắc chắn về tỷ lệ. Nó chỉ là một giới hạn tối đa, nó sẽ không được sử dụng tất cả bộ nhớ. Tôi sẽ chỉ đặt nó cao như bạn cần sau đó thu nhỏ lại nếu cần.
Nicholas Porter

Tôi sẽ thử ram hệ thống - 1gb. Giả sử vm này chỉ để chạy ứng dụng nút này.
Harry Moreno

2
@HarryMoreno Một bộ nhớ hệ thống tốt cho tỷ lệ kích thước không gian tối đa cũ phụ thuộc hoàn toàn vào những gì khác đang chạy trên máy của bạn. Bạn có thể tăng nó theo quyền hạn của hai - hoặc bạn có thể sử dụng bất kỳ số nào. Bạn có thể đặt nó lớn hơn bộ nhớ hệ thống - nhưng bạn sẽ gặp sự cố trao đổi.
Gigimoi

20

tôi đã vật lộn với điều này ngay cả sau khi cài đặt --max-old-space-size.

Sau đó, tôi nhận ra cần phải đặt các tùy chọn - max-old-space-size trước tập lệnh karma.

cũng tốt nhất để chỉ định cả hai cú pháp --max-old-space-size và --max_old_space_size script của tôi cho karma:

node --max-old-space-size=8192 --optimize-for-size --max-executable-size=8192  --max_old_space_size=8192 --optimize_for_size --max_executable_size=8192 node_modules/karma/bin/karma start --single-run --max_new_space_size=8192   --prod --aot

tham khảo https://github.com/angular/angular-cli/issues/1652


5
" tốt nhất để chỉ định cả hai cú pháp --max-old-space-size và --max_old_space_size " - bạn không cần phải làm điều này, chúng là từ đồng nghĩa. Từ nodejs.org/api/cli.html#cli_options : "Tất cả các tùy chọn, bao gồm cả tùy chọn V8, cho phép các từ được phân tách bằng cả hai dấu gạch ngang (-) hoặc dấu gạch dưới (_)."
ZachB

6
kích thước tối đa có thể thực hiện được đã bị xóa và kết thúc bằng một lỗi khi nó được sử dụng: github.com/nodejs/node/issues/13341
crashbus

Tôi đã phải cắt nó ra --max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizevà nó đã hoạt động
Sergey Pleshakov

16

Tôi đã có một vấn đề tương tự trong khi thực hiện xây dựng góc AOT. Theo lệnh đã giúp tôi.

npm install -g increase-memory-limit
increase-memory-limit

Nguồn: https://geeklearning.io/angular-aot-webpack-memory-trick/


1
Chúc mừng làm việc cho tôi, có thể là cần thiếtsudo npm -g install increase-memory-limit --unsafe-perm
Leo

11

fwiw, tìm và sửa một con heo nhớ bằng thứ gì đó như memwatch có thể giúp ích.


10

Các bước để khắc phục sự cố này (Trong Windows) -

  1. Mở dấu nhắc lệnh và gõ %appdata%nhấn enter
  2. Điều hướng đến %appdata%thư mục> npm
  3. Mở hoặc chỉnh sửa ng.cmdtrong trình chỉnh sửa yêu thích của bạn
  4. Thêm --max_old_space_size=8192vào khối IF và ELSE

Tệp của bạn node.cmdtrông như thế này sau khi thay đổi:

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe" "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
)

Đây là Windows cụ thể. OP đã không đề cập bất cứ điều gì về Windows.
Dan Dascalescu

@DanDascalescu Trả lời cập nhật. Cảm ơn bạn đã thông báo
Umang Patwa

6

Biến môi trường sau đây có thể được sử dụng:

NODE_OPTIONS= --max-old-space-size=8192 .

Một lưu ý khác: console.log()cũng tiêu thụ bộ nhớ trong thiết bị đầu cuối.

chỉ cố gắng bình luận console.log () trên terminal. bởi vì điều đó cũng sẽ mất trí nhớ.


6
Đây có phải là một câu trả lời hoặc nhận xét cho một số câu trả lời? Có rất nhiều câu trả lời vớiNODE_OPTIONS= --max-old-space-size=somesize
barbsan

5

nếu bạn muốn thay đổi bộ nhớ trên toàn cầu cho nút (cửa sổ), hãy chuyển đến cài đặt hệ thống nâng cao -> biến môi trường -> biến người dùng mới

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096


4

Tôi chỉ muốn thêm rằng trong một số hệ thống, thậm chí tăng giới hạn bộ nhớ nút --max-old-space-size, nó không đủ và có lỗi hệ điều hành như thế này:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

Trong trường hợp này, có lẽ là do bạn đã đạt đến mmap tối đa cho mỗi quy trình.

Bạn có thể kiểm tra max_map_count bằng cách chạy

sysctl vm.max_map_count

và tăng nó bằng cách chạy

sysctl -w vm.max_map_count=655300

và sửa nó để không được thiết lập lại sau khi khởi động lại bằng cách thêm dòng này

vm.max_map_count=655300

trong /etc/sysctl.conftập tin

Kiểm tra ở đây để biết thêm.

Một phương pháp tốt để phân tích lỗi là chạy quy trình với strace

strace node --max-old-space-size=128000 my_memory_consuming_process.js

3

Gần đây tôi đã gặp phải vấn đề tương tự và gặp phải chủ đề này nhưng vấn đề của tôi là với ReactỨng dụng. Dưới đây thay đổi trong lệnh bắt đầu nút đã giải quyết vấn đề của tôi.

Cú pháp

node --max-old-space-size=<size> path-to/fileName.js

Thí dụ

node --max-old-space-size=16000 scripts/build.js

Tại sao kích thước là 16000 trong kích thước không gian tối đa cũ?

Về cơ bản, nó thay đổi tùy thuộc vào bộ nhớ được phân bổ cho luồng đó và cài đặt nút của bạn.

Làm thế nào để xác minh và đưa ra kích thước phù hợp?

Điều này về cơ bản là ở trong động cơ của chúng tôi v8. đoạn mã dưới đây giúp bạn hiểu Kích thước Heap của công cụ v8 nút cục bộ của bạn.

const v8 = require('v8');
const totalHeapSize = v8.getHeapStatistics().total_available_size;
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
console.log('totalHeapSizeGb: ', totalHeapSizeGb);

2

Tôi vừa gặp vấn đề tương tự với ví dụ EC2 t2.micro có bộ nhớ 1 GB.

Tôi đã giải quyết vấn đề bằng cách tạo tệp hoán đổi bằng url này và đặt biến môi trường sau.

export NODE_OPTIONS=--max_old_space_size=4096

Cuối cùng vấn đề đã biến mất.

Tôi hy vọng điều đó sẽ hữu ích cho tương lai.


1

Chỉ trong trường hợp nó có thể giúp mọi người gặp vấn đề này trong khi sử dụng các ứng dụng nodejs tạo ra việc ghi nhật ký nặng, một đồng nghiệp đã giải quyết vấn đề này bằng cách chuyển (các) đầu ra tiêu chuẩn vào một tệp.


1

Nếu bạn đang cố gắng tự khởi chạy node, nhưng một số phần mềm khác, ví dụ webpackbạn có thể sử dụng biến và cross-envgói môi trường :

$ cross-env NODE_OPTIONS='--max-old-space-size=4096' \
  webpack --progress --config build/webpack.config.dev.js

1

Đối với gói dự án góc, tôi đã thêm dòng dưới đây vào tệp pakage.json của mình trong phần tập lệnh .

"build-prod": "node --max_old_space_size=5120 ./node_modules/@angular/cli/bin/ng build --prod --base-href /"

Bây giờ, để gói mã của tôi, tôi sử dụng npm run build-prodthay vìng build --requiredFlagsHere

hi vọng điêu nay co ich!


0

Nâng cấp nút lên phiên bản mới nhất. Tôi đã vào nút 6.6 với lỗi này và nâng cấp lên 8.9.4 và vấn đề đã biến mất.


0

Trong trường hợp của tôi, tôi đã chạy npm installphiên bản nút trước đó, sau một ngày tôi đã nâng cấp phiên bản nút và ram npm installcho một vài mô-đun. Sau này tôi đã nhận được lỗi này. Để khắc phục sự cố này, tôi đã xóa thư mục node_module khỏi mỗi dự án và chạy npm installlại.

Hy vọng điều này có thể khắc phục vấn đề.

Lưu ý: Điều này đã xảy ra trên máy cục bộ của tôi và nó chỉ được sửa trên máy cục bộ.


0

Lệnh này hoạt động hoàn hảo. Tôi có ram 8GB trong máy tính xách tay của mình, vì vậy tôi đặt kích thước = 8192. Đó là tất cả về ram và bạn cũng cần đặt tên tệp. Tôi chạy lệnh npm run build đó là lý do tại sao tôi sử dụng build.js .

node --expose-gc --max-old-space-size=8192 node_modules/react-scripts/scripts/build.js

0

Trong trường hợp của tôi, tôi đã nâng cấp phiên bản node.js lên phiên bản mới nhất và nó hoạt động như một bùa mê.


Xin chào Angela và chào mừng bạn đến với SO! Bạn có thể chỉ định phiên bản chính xác của Node.js mà bạn đã cập nhật cho người đọc trong tương lai không? Cảm ơn!
kant312

Tôi đã nâng cấp lên Phiên bản LTS mới nhất: 12,18.0
Angela Rana
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.