Jak określić poprawny „maksymalny-stary-rozmiar-miejsca” dla node.js?

100

Mam problemy ze zrozumieniem, jak działa Node.js na podstawie parametru max-old-space-size.

Na przykład w moim przypadku uruchamiam dwie t2.smallinstancje AWS (2 GB pamięci RAM).

Nie wiem dlaczego, ale ustawiłem max-old-space-size=4096(4 GB). Co w tym przypadku robi node? Czy ta konfiguracja może prowadzić do możliwego błędu alokacji pamięci?

Jak określić poprawną wartość na max-old-space-sizepodstawie zasobów serwera?

Moja aplikacja stale zwiększa wykorzystanie pamięci i staram się zrozumieć wszystko na temat wewnętrznych elementów węzła.

Borjante
źródło
8
Teraz dodaję komentarz, widząc, że ten widok bardzo się uspokaja. Zajęło mi cały tydzień, zanim zdałem sobie sprawę, że moja aplikacja NodeJS nie ma wycieku pamięci, ale moduł odśmiecania pamięci nigdy się nie włączył. Pamiętaj o tym w systemach z małą ilością pamięci, takich jak instancje t2.micro lub t2.small. Serwer ulegnie awarii z powodu niedostępnej pamięci RAM.
Borjante
Czy istniał sposób, aby zmusić śmieciarza do włączenia się?
ZG101
@Borjante dlaczego nie działał garbage collector?
boski
2
Skonfigurowany maksymalny rozmiar starego miejsca miał wyższy limit niż całkowita ilość pamięci RAM, którą posiadała maszyna.
Borjante
Warto spróbować --optimize-for-sizezmniejszyć zużycie pamięci.
Constantinos

Odpowiedzi:

135

„Stare miejsce” to największa i najbardziej konfigurowalna sekcja zarządzanej (czyli zbieranej bezużytecznie) stosu V8 ​​(czyli miejsca, w którym znajdują się obiekty JavaScript), a --max-old-space-size flaga kontroluje jej maksymalny rozmiar. Gdy zużycie pamięci zbliża się do limitu, V8 poświęci więcej czasu na czyszczenie pamięci w celu zwolnienia nieużywanej pamięci.

Jeśli zużycie pamięci sterty (tj. Obiektów na żywo, których GC nie może zwolnić) przekroczy limit, V8 zawiesi twój proces (z powodu braku alternatywy), więc nie chcesz ustawiać go zbyt nisko. Oczywiście, jeśli ustawisz go zbyt wysoko, dodatkowe użycie sterty, na które pozwoli V8, może spowodować wyczerpanie pamięci w całym systemie (i zamianę lub zabicie przypadkowych procesów, z braku alternatywy).

Podsumowując, na komputerze z 2 GB pamięci prawdopodobnie --max-old-space-sizeustawiłbym około 1,5 GB, aby zostawić trochę pamięci do innych zastosowań i uniknąć zamiany.

jmrk
źródło
6
Właśnie to miałem nadzieję uzyskać odpowiedź, opisując skrajny przypadek, w którym system lub węzeł zabraknie pamięci.
Borjante
2
@jmrk: Wygląda na to, że masz całkowitą rację, ale kiedy używam 2 GB RAM i 4 GB swap i ustawię „--max-old-space-size” na 4 GB, proces węzła zużywa całą pamięć RAM i utknie na 1,9 GB. Pytanie brzmi: „Dlaczego zamiana jest unikaniem używania ??” (wersja 8.11.1 węzła)
Manish Trivedi
1
Flaga powinna mieć pierwszeństwo przed wszystkim innym. Sprawdź dokładnie literówki.
jmrk
2
Od d8 --help:--max-old-space-size (max size of the old space (in Mbytes))
jmrk
21

Aktualizacja 2020

Te opcje są teraz oficjalnie udokumentowane według węzła . W przypadku maszyny 2 GB prawdopodobnie powinieneś użyć:

NODE_OPTIONS=--max-old-space-size=1536

Aby określić ilość do wykorzystania : Możesz sprawdzić dostępną pamięć na komputerze z systemem Linux za pomocą free -m. Należy pamiętać, że można użyć free, a buffers/cachepamięć łączy się, jak buffers/cachemożna wyrzucić (te bufory i cache są sposobem miły w użyciu inaczej nieużywaną pamięć).

Zwróć uwagę na oficjalną dokumentację dlamax-old-space-size wzmianek:

Na komputerze z 2 GB pamięci rozważ ustawienie tego na 1536 (1,5 GB)

Stąd powyższa wartość. Weź pod uwagę, że ilość pamięci potrzebnej dla podstawowego systemu operacyjnego nie zmienia się zbytnio, więc możesz szczęśliwie zrobić 3.5 na maszynie 4 GB itp.

mikemaccana
źródło
2
Z linku udostępnionego w dokumentach Node.js jest napisane: „Na komputerze z 2 GB pamięci rozważ ustawienie 1536 (1,5 GB)”
Idan Dagan,
1
Dzięki @IdanDagan dodam to do odpowiedzi.
mikemaccana
11

Ten błąd występuje, gdy pamięć przydzielona aplikacji wykonującej jest mniejsza niż wymagana pamięć. Domyślnie limit pamięci w Node.js wynosi 512 MB. Aby zwiększyć tę kwotę, musisz ustawić argument limitu pamięci —-max-old-space-size. Pomoże to uniknąć problemu z limitem pamięci.

node --max-old-space-size=1024 index.js #increase to 1gb
node --max-old-space-size=2048 index.js #increase to 2gb
node --max-old-space-size=3072 index.js #increase to 3gb
node --max-old-space-size=4096 index.js #increase to 4gb
node --max-old-space-size=5120 index.js #increase to 5gb
node --max-old-space-size=6144 index.js #increase to 6gb
node --max-old-space-size=7168 index.js #increase to 7gb
node --max-old-space-size=8192 index.js #increase to 8gb

https://medium.com/@vuongtran/how-to-solve-process-out-of-memory-in-node-js-5f0de8f8464c

S. V
źródło
i powinno być więcej niż przydzielona pamięć RAM
HD ..
Nie jestem już pewien, czy to już prawda. Z pewnością w jednym systemie mam dostęp do działającego węzła 10.20.1, widzę (z node --v8-options), że domyślnie zgłaszany jest 4096 i bez ustawiania używanego przeze mnie max-old-space-sizezestawu testów uzyskuje przydzielone do 1,5 Gb bez żadnych problemów. Artykuł w medium, do którego prowadzi link, pochodzi z 2016 roku, więc prawdopodobnie od czasu jego napisania sytuacja się zmieniła.
JaySeeAre
1
Trudno o potwierdzenie tego; Nie mogę znaleźć niczego wyraźnego w dokumentacji dla V8 lub Node. Inny system, który mam, zgłasza domyślny dla wersji 10, 12 i 14. jako 0. FWIW Znalazłem kilku nowszych blogerów podających maksymalną pamięć jako 1,5 Gb ( tejom.github.io/general/nodejs/v8/debugging/2017/ 01/16 /… ) i że v12 ma dynamiczne maksimum oparte na systemie ( idginsiderpro.com/article/3257673/ ... ).
JaySeeAre
4
node -e "console.log(`node heap limit = ${require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)"-> wersja 12.18.0 i wersja 14.3.0 -> 2096 MB, wersja 10.20.1 -> 1432 MB
JaySeeAre
2
@JaySeeAre, dzięki za to polecenie, aby wyświetlić plik heap_size_limit. W przypadku normalnej powłoki UNIX należy ją cytować inaczej:node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'
Sam Watkins
-9

Jeśli chcesz, aby wszystko działało z projektu, nad którym pracujesz, wykonaj dwa kroki:

  1. W twoim projekcie cd to node_module / @ angular cd node_module / @ angular

  2. Teraz uruchom poniższe polecenie export NODE_OPTIONS = - max-old-space-size = 8192

satish suryawanshi
źródło
18
Po co miałoby iść do katalogu @angular, aby ustawić zmienną środowiska?
mgamsjager