Node.js belleği yetersiz


247

Bugün RAID dosya dizinini yenilemek için dosya sistemi indeksleme için komut dosyamı çalıştırdım ve 4 saat sonra aşağıdaki hata ile çöktü:

[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

Sunucu 16GB RAM ve 24GB SSD takas ile donatılmıştır. Senaryomun 36GB belleği aştığından şüpheliyim. En azından yapmamalı

Komut dosyası, dosya meta verileri içeren Nesneler Dizisi olarak depolanan dosyaların dizinini oluşturur (değişiklik tarihleri, izinler, vb. Büyük veri yok)

Komut dosyasının tamamını burada bulabilirsiniz: http://pastebin.com/mjaD76c3

Zaten beni zorlayan bu senaryo ile geçmişte garip düğüm sorunları yaşadım. Dize gibi büyük dosyalar üzerinde çalışırken, düğüm birden fazla dosyaya bölündü. Büyük veri kümeleri ile nodejs bellek yönetimini geliştirmenin bir yolu var mı?

Yanıtlar:


315

Eğer doğru hatırlamıyorsam, V8'deki bellek kullanımı için elle 1,7 GB civarında katı bir standart sınır vardır.

Ürünlerimizden birinde konuşlandırma komut dosyamızda bu çözümü izledik:

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

Ayrıca yeni bir boşluk komutu olurdu ama burada okuduğum gibi: a-tour-of-v8-garbage-collection yeni alan sadece yeni oluşturulan kısa vadeli verileri toplar ve eski alan olması gereken tüm referans veri yapılarını içerir sizin durumunuz en iyi seçenek.


Aynı şekilde bu yapılandırma, çerçevede bağımsız olarak nodej'ler içindir. @ Simer
Felix

Açısal 4 ile geliştiriyorum ve aynı sorunu alıyorum, açısal uygulama için File.js dosyanız ne olmalı?
Vikram

@VikramSingh kullanıyorsunuz ng serveveya ng build/ dist klasörünün sonucunu express gibi başka bir web sunucusu tarafından dağıtıyor musunuz? Ancak Açısal projeniz standart 1,7 GB'den fazla Bellek kullanıyorsa, uygulamanızda mimari bir sorun yaşayabileceğinizi düşünüyor musunuz? Nmp start ile geliştirme env'sini kullanıyormuşsunuz gibi görünüyor belki de bunun için bir çözüm github.com/mgechev/angular-seed/issues/2063
Felix

Açısal cli ve aot (dist klasörü) ile ng yapı kullanıyorum
Vikram

2
endeksi, sunucuyu başlatmak için kullandığınız js dosyası @Techdive
Basit

77

Herkesin düğüm özelliklerini doğrudan ayarlayamadığı bir ortamda bu durumda çalışması durumunda (benim durumumda bir oluşturma aracı):

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

Komut satırına iletemiyorsanız, bir ortam değişkeni kullanarak düğüm seçeneklerini ayarlayabilirsiniz.


"... bir ortam değişkeni kullanarak düğüm seçeneklerini ayarlayın" derken ne demek istediğinizi açıklar mısınız?
Keselme

6
@Keselme Ortam değişkeni, tüm işlemlerin verileri okuyabileceği sunucuda ayarlanmış bir değişkendir. Sunucunuza bir SSH terminali açın ve şunu yazın: MY_VAR = merhaba sonra yazın: echo $ MY_VAR. Terminalde "merhaba" yazdığını göreceksiniz. Bir ortam değişkeni belirlediniz ve tekrar okudunuz.
Rob Evans

Ubuntu 18.04 üzerinde çalıştı, sadece bashrc dosyasına ihracat komutunu ekledi
Rahal Kanishka

76

Düğümün bellek kullanımını genel olarak artırmak istiyorsanız - yalnızca tek bir komut dosyası değil, ortam değişkenini şöyle aktarabilirsiniz:
export NODE_OPTIONS=--max_old_space_size=4096

Sonra gibi derlemeleri çalıştırırken dosyaları ile oynamak gerekmez npm run build.


1
Ek bir kolaylık olarak bash_profile veya zsh profiline ekleyin.
Tropicalrambler

24

VSCode ile hata ayıklamaya çalışırken bu sorunla karşılaştım, bu yüzden sadece bu hata ayıklama kurulumunuza argüman ekleyebilirsiniz nasıl eklemek istedim.

Bunu, runtimeArgsyapılandırmanızın özelliğine ekleyebilirsiniz launch.json.

Aşağıdaki örneğe bakın.

{
"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üğüm sunucunuzu başlattığınızda daha fazla belleğe nasıl izin verileceği hakkında ek bilgi eklemek için bazı bayrak değerleri.

1 GB - 8 GB

#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 

biri 2 gücünde arttırmaya devam edebilir? biri sistem belleğinden daha büyük ayarlamalı mı? değilse, iyi bir sistem belleği / maksimum eski alan boyutu oranı nedir?
Harry Moreno

3
@HarryMoreno Aslında istediğiniz herhangi bir sayı değeri koyabilirsiniz. Gücü 2 olmak zorunda değildir. Orandan emin değilim. Bu sadece bir maksimum sınır, tüm hafızayı kullanmayacak. İstediğiniz kadar yükseğe ayarlayabilirim, sonra gerekirse ölçeklendirin.
Nicholas Porter

Sistem koçu vereceğim - 1GB denemeliyim. Bu vm'nin yalnızca bu düğüm uygulamasını çalıştırmak için olduğunu varsayarsak.
Harry Moreno

2
@HarryMoreno İyi bir sistem belleği - maksimum eski alan boyutu oranı, tamamen makinenizde başka nelerin çalıştığına bağlıdır. Onu iktidarın gücüyle artırabilir ya da herhangi bir sayı kullanabilirsiniz. Sistem belleğinden daha büyük ayarlayabilirsiniz - ancak takas sorunları ile karşılaşırsınız.
Gigimoi

20

- max-old-space-size ayarladıktan sonra bile bu ile mücadele ediyordu.

Sonra seçenekleri - max-eski-uzay-boyutu karma komut dosyası önce koymanız gerektiğini fark ettim.

Ayrıca her iki sözdizimini belirtmek için en iyisi - max-old-space-size ve --max_old_space_size karma için komutumu:

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

referans https://github.com/angular/angular-cli/issues/1652


5
" her iki sözdizimini belirtmek için en iyisi - max-old-space-size ve --max_old_space_size " - bunu yapmanız gerekmez, eş anlamlılardır. Gönderen nodejs.org/api/cli.html#cli_options : "(-) Tüm seçenekler, V8 seçenekler de dahil olmak kelimeler hem tire ile ayrılmış izin veya çizgi (_)."
ZachB

6
max-yürütülebilir-size kaldırıldı ve kullanıldığında bir hatayla bitiyor: github.com/nodejs/node/issues/13341
crashbus

Kesmek zorunda kaldım --max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizeve işe yaradı
Sergey Pleshakov



10

Bu sorunu giderme adımları (Windows'ta) -

  1. Komut istemini açın ve %appdata%enter tuşuna basın
  2. %appdata%> Npm klasörüne gidin
  3. ng.cmdFavori düzenleyicinizde Aç veya Düzenle
  4. --max_old_space_size=8192IF ve ELSE bloğuna ekleyin

Kişisel node.cmddosya değişiklikten sonra şuna benzer:

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

Bu Windows'a özgüdür. OP, Windows hakkında hiçbir şeyden bahsetmedi.
Dan Dascalescu

@DanDascalescu Güncellenmiş Yanıt. Bildirim için teşekkürler
Umang Patwa

6

Aşağıdaki ortam değişkeni kullanılabilir:

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

Başka bir not: console.log()terminaldeki belleği de tüketir.

sadece terminaldeki console.log () 'u yorumlamaya çalıştı. çünkü bu da hafızayı alacak.


6
Bu cevap veya cevap mı? NODE_OPTIONS= --max-old-space-size=somesize
barbsan

5

düğümü (windows) için belleği global olarak değiştirmek istiyorsanız gelişmiş sistem ayarlarına gidin -> ortam değişkenleri -> yeni kullanıcı değişkeni

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


4

Sadece bazı sistemlerde, düğüm bellek sınırını arttırmakla bile --max-old-space-size, yeterli olmadığını ve böyle bir işletim sistemi hatası olduğunu eklemek istiyorum :

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

Bu durumda, muhtemelen işlem başına maksimum mmap'e ulaşmış olmanızdır.

Max_map_count komutunu çalıştırarak kontrol edebilirsiniz.

sysctl vm.max_map_count

ve koşarak arttırmak

sysctl -w vm.max_map_count=655300

ve bu satırı ekleyerek yeniden başlattıktan sonra sıfırlanmayacak şekilde düzeltin

vm.max_map_count=655300

içinde /etc/sysctl.confdosyaya.

Kontrol burada daha fazla bilgi için.

Hatayı analiz etmek için iyi bir yöntem, strace

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

3

Geçenlerde aynı sorunla karşılaştım ve bu konuya rastladım ama benim sorunum ReactApp ile oldu. Düğüm start komutundaki aşağıdaki değişiklikler sorunlarımı çözdü.

Sözdizimi

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

Misal

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

Neden boyut en fazla eski alan boyutunda 16000?

Temel olarak, bu iş parçacığına ayrılan belleğe ve düğüm ayarlarınıza bağlı olarak değişir.

Doğru boyut nasıl doğrulanır ve verilir?

Bu temelde motorumuzda kalmak v8. Aşağıdaki kod, yerel düğüm v8 motorunuzun Yığın Boyutunu anlamanıza yardımcı olur.

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

2

1 GB belleğe sahip EC2 örneğim t2.micro ile aynı problemle karşılaştım.

Bu url'yi kullanarak takas dosyası oluşturarak ve aşağıdaki ortam değişkenini ayarlayarak sorunu çözdüm.

export NODE_OPTIONS=--max_old_space_size=4096

Sonunda sorun gitti.

Umarım gelecek için faydalı olur.


1

Yoğun günlük kaydı üreten nodejs uygulamalarını kullanırken bu sorunu yaşayanların yardımcı olması durumunda, bir meslektaşım bu sorunu standart çıktıları bir dosyaya aktararak çözdü.


1

nodeKendini değil , başka bir yazılımı başlatmaya çalışıyorsanız , örneğin webpackortam değişkenini ve cross-envpaketini kullanabilirsiniz:

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

1

Açısal proje donatılacak için, ben ettik için sınırının altında ilave benim pakage.json dosyanın komut bölümüne.

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

Şimdi, kodumu paketlemek için npm run build-prodyerineng build --requiredFlagsHere

Bu yardımcı olur umarım!


0

Düğümü en son sürüme yükseltin. Bu hata ile 6.6 düğümdeydim ve 8.9.4'e yükselttim ve sorun ortadan kalktı.


0

Benim durumumda npm install, düğümün önceki sürümünde koştum , bir günden sonra npm installbirkaç modül için düğüm sürümünü ve koçunu yükselttim . Bundan sonra bu hatayı alıyordum. Bu sorunu gidermek için her projeden node_module klasörünü sildim ve koştumnpm install tekrar .

Umarım bu sorunu çözebilir.

Not: Bu, yerel makinemde oluyordu ve yalnızca yerel makinede düzeltildi.


0

Bu komut mükemmel çalışıyor. Dizüstü bilgisayarımda 8GB RAM var, bu yüzden boyutu = 8192 olarak ayarladım. Her şey ram ile ilgilidir ve ayrıca dosya adını ayarlamanız gerekir. Ben npm run build komutunu çalıştırıyorum , bu yüzden build.js kullandım .

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

0

Benim durumumda, node.js sürümünü en son sürüme yükselttim ve bir cazibe gibi çalıştı.


Merhaba Angela ve SO'ya hoş geldiniz! Gelecekteki okuyucular için güncellediğiniz Node.js'nin tam sürümünü belirtebilir misiniz? Teşekkürler!
kant312

Son LTS sürümüne geçtim Sürüm: 12.18.0
Angela Rana
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.