Node.js จำนวนมากออกจากหน่วยความจำ


247

วันนี้ฉันรันสคริปต์ของฉันสำหรับการทำดัชนีระบบไฟล์เพื่อรีเฟรชดัชนีไฟล์ RAID และหลังจาก 4 ชม. มันล้มเหลวด้วยข้อผิดพลาดต่อไปนี้:

[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

เซิร์ฟเวอร์นั้นมาพร้อมกับ 16gb RAM และ 24GB SSD swap ฉันสงสัยอย่างยิ่งว่าสคริปต์ของฉันมีหน่วยความจำเกิน 36GB อย่างน้อยก็ไม่ควร

สคริปต์สร้างดัชนีของไฟล์ที่เก็บไว้เป็น Array of Objects ด้วยเมตาดาต้าไฟล์ (วันที่แก้ไข, การอนุญาต, ฯลฯ ไม่มีข้อมูลขนาดใหญ่)

นี่คือรหัสสคริปต์แบบเต็ม: http://pastebin.com/mjaD76c3

ฉันเคยประสบปัญหาโหนดแปลก ๆ ในอดีตกับสคริปต์นี้สิ่งที่บังคับฉันเช่น แบ่งดัชนีออกเป็นหลายไฟล์เมื่อโหนดทำงานผิดพลาดเมื่อทำงานกับไฟล์ขนาดใหญ่เช่น String มีวิธีใดในการปรับปรุงการจัดการหน่วยความจำ nodejs ด้วยชุดข้อมูลขนาดใหญ่?

คำตอบ:


315

หากฉันจำได้อย่างถูกต้องมีข้อ จำกัด มาตรฐานที่เข้มงวดสำหรับการใช้หน่วยความจำใน V8 ประมาณ 1.7 GB หากคุณไม่เพิ่มด้วยตนเอง

ในหนึ่งในผลิตภัณฑ์ของเราเราปฏิบัติตามวิธีแก้ปัญหานี้ในสคริปต์ปรับใช้ของเรา:

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

จะมีคำสั่ง space ใหม่ แต่เมื่อฉันอ่านที่นี่: a-tour-of-v8-garbage-collectionพื้นที่ใหม่จะรวบรวมข้อมูลระยะสั้นที่สร้างขึ้นใหม่เท่านั้นและพื้นที่เก่ามีโครงสร้างข้อมูลอ้างอิงทั้งหมดที่ควรอยู่ใน กรณีของคุณเป็นตัวเลือกที่ดีที่สุด


ในทำนองเดียวกัน config นี้สำหรับ nodejs อย่างอิสระบนเฟรมเวิร์ก @ Simer
Felix

ฉันกำลังพัฒนาด้วย angular 4 และได้รับปัญหาเดียวกันไฟล์ yourFile.js สำหรับแอพเชิงมุมคืออะไร
Vikram

@VikramSingh คุณกำลังใช้ng serveหรือคุณเผยแพร่ผลของng buildโฟลเดอร์ / dist โดยเว็บเซิร์ฟเวอร์อื่นเช่น express หรือไม่ แต่ถ้าโครงการแองกูลาร์ของคุณใช้มากกว่าหน่วยความจำ 1.7GB มาตรฐานมากกว่าที่คุณอาจจะมีปัญหาสถาปัตยกรรมในแอปพลิเคชันของคุณ? ดูเหมือนว่าคุณกำลังใช้การพัฒนา env ด้วย nmp start บางทีนี่อาจเป็นคำตอบสำหรับมันgithub.com/mgechev/angular-seed/issues/2063
Felix

ฉันใช้ ng build กับ cli เชิงมุมและ aot (dist dist)
Vikram

2
ดัชนีไฟล์ js @Techdive ที่คุณใช้ในการเริ่มต้นเซิร์ฟเวอร์
Basit

77

ในกรณีที่ทุกคนพบเจอสิ่งนี้ในสภาพแวดล้อมที่พวกเขาไม่สามารถตั้งค่าคุณสมบัติโหนดได้โดยตรง (ในกรณีของฉันเป็นเครื่องมือสร้าง):

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

คุณสามารถตั้งค่าตัวเลือกโหนดโดยใช้ตัวแปรสภาพแวดล้อมหากคุณไม่สามารถส่งผ่านพวกเขาในบรรทัดคำสั่ง


คุณกรุณาอธิบายสิ่งที่คุณหมายถึงเมื่อคุณพูดว่า "... ตั้งค่าตัวเลือกโหนดโดยใช้ตัวแปรสภาพแวดล้อม .. "?
Keselme

6
@ Keselme ตัวแปรสภาพแวดล้อมเป็นตัวแปรที่ได้รับการตั้งค่าบนเซิร์ฟเวอร์ที่กระบวนการทั้งหมดสามารถอ่านข้อมูลได้ เปิดเทอร์มินัล SSH ไปยังเซิร์ฟเวอร์ของคุณและพิมพ์: MY_VAR = สวัสดีแล้วพิมพ์: echo $ MY_VAR คุณจะเห็นว่ามันพิมพ์ "hello" ใน terminal คุณเพิ่งตั้งค่าตัวแปรสภาพแวดล้อมและอ่านมันกลับมา
Rob Evans

ทำงานบน Ubuntu 18.04 เพียงแค่เพิ่มคำสั่งการส่งออกไปยังแฟ้ม bashrc ของฉัน
Rahal Kanishka

76

หากคุณต้องการเพิ่มการใช้หน่วยความจำของโหนดทั่วโลก - ไม่เพียง แต่สคริปต์เดียวคุณสามารถส่งออกตัวแปรสภาพแวดล้อมเช่นนี้:
export NODE_OPTIONS=--max_old_space_size=4096

จากนั้นคุณไม่จำเป็นต้องเล่นกับไฟล์เมื่อใช้งานบิล npm run buildด์


1
เพื่อเพิ่มความสะดวกให้เพิ่มในโปรไฟล์ bash_profile หรือ zsh
Tropicalrambler

24

ฉันพบปัญหานี้เมื่อพยายามดีบักด้วย VSCode ดังนั้นเพียงแค่ต้องการเพิ่มนี่คือวิธีที่คุณสามารถเพิ่มอาร์กิวเมนต์ในการตั้งค่าการดีบักของคุณ

คุณสามารถเพิ่มไปยังทรัพย์สินของการตั้งค่าของคุณruntimeArgslaunch.json

ดูตัวอย่างด้านล่าง

{
"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

นี่คือค่าสถานะบางอย่างเพื่อเพิ่มข้อมูลเพิ่มเติมเกี่ยวกับวิธีการอนุญาตหน่วยความจำเพิ่มเติมเมื่อคุณเริ่มต้นโหนดเซิร์ฟเวอร์ของคุณ

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 


สามารถเพิ่มขึ้นเรื่อย ๆ ได้ด้วยพลังของ 2 หรือไม่? ควรตั้งค่าให้มีขนาดใหญ่กว่าหน่วยความจำระบบหรือไม่ ถ้าไม่ใช่หน่วยความจำของระบบที่ดีต่ออัตราส่วนพื้นที่ว่างขนาดสูงสุด
Harry Moreno

3
@HarryMoreno คุณสามารถใส่ค่าตัวเลขที่คุณต้องการได้ ไม่จำเป็นต้องอยู่ในระดับ 2 ไม่แน่ใจเกี่ยวกับอัตราส่วน เป็นเพียงขีด จำกัด สูงสุดมันจะไม่ใช้หน่วยความจำทั้งหมด ฉันจะตั้งให้สูงที่สุดเท่าที่คุณต้องการจากนั้นลดขนาดถ้าจำเป็น
Nicholas Porter

ฉันจะให้แรมระบบ - 1gb ลอง สมมติว่า vm นี้ใช้สำหรับเรียกใช้แอปโหนดนี้เท่านั้น
Harry Moreno

2
@HarryMoreno หน่วยความจำของระบบที่ดีต่ออัตราส่วนพื้นที่ว่างขนาดสูงสุดจะขึ้นอยู่กับสิ่งที่เรียกใช้บนเครื่องของคุณ คุณสามารถเพิ่มมันด้วยพลังของสอง - หรือคุณสามารถใช้หมายเลขใด ๆ คุณสามารถตั้งค่าได้มากกว่าหน่วยความจำระบบ แต่คุณจะพบปัญหาการสลับ
Gigimoi

20

ฉันกำลังดิ้นรนกับสิ่งนี้แม้หลังจากการตั้งค่า --max-old-space-size

จากนั้นฉันก็รู้ว่าต้องใส่ตัวเลือก - max-old-space-size ก่อนสคริปต์กรรม

ยังดีที่สุดในการระบุทั้งไวยากรณ์ --max-old-space-size และ --max_old_space_size สคริปต์ของฉันสำหรับกรรม:

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

การอ้างอิงhttps://github.com/angular/angular-cli/issues/1652


5
" ดีที่สุดในการระบุทั้งไวยากรณ์ --max-old-space-size และ --max_old_space_size " - คุณไม่จำเป็นต้องทำสิ่งนี้เพราะเป็นคำพ้องความหมาย จากnodejs.org/api/cli.html#cli_options : "ตัวเลือกทั้งหมดรวมถึงตัวเลือก V8 อนุญาตให้แยกคำด้วยเครื่องหมายขีดกลาง (-) หรือขีดล่าง (_)"
ZachB

6
max-executable-size ถูกลบและสิ้นสุดในข้อผิดพลาดเมื่อมีการใช้งาน: github.com/nodejs/node/issues/13341
crashbus

ฉันต้องตัดมัน--max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizeและมันก็ใช้ได้
Sergey Pleshakov

16

ฉันมีปัญหาที่คล้ายกันในขณะที่ทำการสร้าง AOT เชิงมุม คำสั่งต่อไปนี้ช่วยฉัน

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

ที่มา: https://geeklearning.io/angular-aot-webpack-memory-trick/


1
ไชโยทำงานให้ฉันก็อาจจำเป็นต้องsudo npm -g install increase-memory-limit --unsafe-perm
Leo


10

ขั้นตอนในการแก้ไขปัญหานี้ (ใน Windows) -

  1. เปิดพรอมต์คำสั่งแล้ว%appdata%กด enter
  2. ไปที่%appdata%โฟลเดอร์> npm
  3. เปิดหรือแก้ไขng.cmdในตัวแก้ไขรายการโปรดของคุณ
  4. เพิ่ม--max_old_space_size=8192ไปยังบล็อก IF และ ELSE

node.cmdไฟล์ของคุณมีลักษณะเช่นนี้หลังจากการเปลี่ยนแปลง:

@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" %*
)

นี่คือเฉพาะ Windows OP ไม่ได้พูดถึงอะไรเกี่ยวกับ Windows
Dan Dascalescu

@DanDascalescu อัพเดตคำตอบแล้ว ขอบคุณที่แจ้งให้ทราบ
Umang Patwa

6

สามารถใช้ตัวแปรสภาพแวดล้อมต่อไปนี้:

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

หมายเหตุอื่น: console.log()ยังใช้หน่วยความจำในเครื่องด้วย

เพิ่งพยายามคอมเม้นต์ console.log () บนเทอร์มินัล เพราะนั่นจะใช้หน่วยความจำด้วย


6
นี่เป็นคำตอบหรือแสดงความคิดเห็นต่อคำตอบหรือไม่? มีคำตอบมากมายด้วยNODE_OPTIONS= --max-old-space-size=somesize
barbsan

5

หากคุณต้องการเปลี่ยนหน่วยความจำร่วมสำหรับโหนด (windows) ให้ไปที่การตั้งค่าระบบขั้นสูง -> ตัวแปรสภาพแวดล้อม -> ตัวแปรผู้ใช้ใหม่

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

4

ฉันลอง code รหัสด้านล่างและมันใช้งานได้ดี✌

  • เปิดเทอร์มินัลจากโปรเจ็กต์ root dir
  • ดำเนินการ cmd เพื่อกำหนดขนาดใหม่

    set NODE_OPTIONS=--max_old_space_size=8172

หรือคุณสามารถตรวจสอบลิงค์สำหรับข้อมูลเพิ่มเติม https://github.com/nodejs/node/issues/10137#issuecomment-487255987


4

ฉันแค่ต้องการเพิ่มสิ่งนั้นในบางระบบแม้เพิ่มขีด จำกัด หน่วยความจำของโหนดด้วย--max-old-space-sizeแต่ก็ไม่เพียงพอและมีข้อผิดพลาดของระบบปฏิบัติการเช่นนี้:

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

ในกรณีนี้อาจเป็นเพราะคุณมาถึง mmap สูงสุดต่อกระบวนการ

คุณสามารถตรวจสอบ max_map_count โดยเรียกใช้

sysctl vm.max_map_count

และเพิ่มโดยการเรียกใช้

sysctl -w vm.max_map_count=655300

และแก้ไขไม่ให้รีเซ็ตหลังจากรีบูตโดยเพิ่มบรรทัดนี้

vm.max_map_count=655300

ใน/etc/sysctl.confไฟล์

ตรวจสอบที่นี่สำหรับข้อมูลเพิ่มเติม

วิธีที่ดีในการวิเคราะห์ข้อผิดพลาดคือโดยเรียกใช้กระบวนการด้วย strace

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

3

ฉันประสบปัญหาเดียวกันนี้เมื่อเร็ว ๆ นี้และได้พบกับเธรดนี้ แต่ปัญหาของฉันคือReactแอพ การเปลี่ยนแปลงด้านล่างในคำสั่งโหนดเริ่มต้นแก้ไขปัญหาของฉัน

วากยสัมพันธ์

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

ตัวอย่าง

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

ทำไมขนาดถึง 16000 ในขนาดพื้นที่สูงสุดเก่า?

โดยทั่วไปจะแตกต่างกันไปขึ้นอยู่กับหน่วยความจำที่จัดสรรให้กับเธรดนั้นและการตั้งค่าโหนดของคุณ

วิธีการตรวจสอบและให้ขนาดที่เหมาะสม?

v8นี้เป็นพื้นอยู่ในเครื่องยนต์ของเรา โค้ดด้านล่างช่วยให้คุณเข้าใจขนาดฮีปของเอ็นจินโหนด v8 ในเครื่องของคุณ

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

2

ฉันเพิ่งพบปัญหาเดียวกันกับอินสแตนซ์ EC2 ของฉัน t2.micro ซึ่งมีหน่วยความจำ 1 GB

ฉันแก้ไขปัญหาด้วยการสร้างไฟล์สลับโดยใช้url นี้และตั้งค่าตัวแปรสภาพแวดล้อมต่อไปนี้

export NODE_OPTIONS=--max_old_space_size=4096

ในที่สุดปัญหาได้หายไป

ฉันหวังว่าจะเป็นประโยชน์สำหรับอนาคต


1

ในกรณีที่อาจช่วยคนที่มีปัญหานี้ในขณะที่ใช้แอป nodejs ที่สร้างการบันทึกจำนวนมากเพื่อนร่วมงานแก้ไขปัญหานี้โดยการส่งออกมาตรฐานไปยังไฟล์


1

หากคุณกำลังพยายามที่จะเปิดตัวไม่ได้nodeตัวเอง แต่บางนุ่มอื่น ๆ เช่นwebpackคุณสามารถใช้ตัวแปรสภาพแวดล้อมและcross-envแพคเกจ:

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

1

สำหรับการรวมโครงการเชิงมุมฉันได้เพิ่มบรรทัดด้านล่างลงในไฟล์pakage.jsonของฉันในส่วนสคริปต์

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

ตอนนี้เพื่อรวมรหัสของฉันฉันใช้npm run build-prodแทนng build --requiredFlagsHere

หวังว่านี่จะช่วยได้!



0

ในกรณีของฉันฉันได้ทำงานnpm installในโหนดรุ่นก่อนหน้าหลังจากวันหนึ่งฉันอัพเกรดรุ่นโหนดและ ram npm installสำหรับโมดูลไม่กี่ หลังจากนี้ฉันได้รับข้อผิดพลาดนี้ เพื่อแก้ไขปัญหานี้ฉันได้ลบโฟลเดอร์ node_module จากแต่ละโครงการและรันnpm installอีกครั้ง

หวังว่าสิ่งนี้อาจแก้ไขปัญหาได้

หมายเหตุ: สิ่งนี้เกิดขึ้นในเครื่องของฉันและได้รับการแก้ไขในเครื่องในท้องถิ่นเท่านั้น


0

คำสั่งนี้ทำงานได้อย่างสมบูรณ์ ฉันมี RAM 8GB ในแล็ปท็อปของฉันฉันเลยกำหนดขนาด = 8192 มันคือทั้งหมดที่เกี่ยวกับ ram และคุณต้องตั้งชื่อไฟล์ ผมทำงานNPM วิ่งสร้างคำสั่งที่ว่าทำไมผมใช้build.js

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

0

ในกรณีของฉันฉันปรับรุ่น node.js เป็นรุ่นล่าสุดและใช้งานได้อย่างมีเสน่ห์


สวัสดี Angela และยินดีต้อนรับสู่ SO! คุณอาจระบุเวอร์ชันที่แน่นอนของ Node.js ที่คุณอัปเดตเป็นสำหรับผู้อ่านในอนาคตได้หรือไม่ ขอบคุณ!
kant312

ฉันอัพเกรดเป็นเวอร์ชั่น LTS ล่าสุด: 12.18.0
แองเจลารานา
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.