FATAL ERROR: CALL_AND_RETRY_LAST Alokacja nie powiodła się - brak pamięci


187

Wersja węzła to v0.11.13

Zużycie pamięci podczas awarii zgodnie z tym, że się sudo topnie podnosi3%

Kod odtwarzający ten błąd:

var request = require('request')
var nodedump = require('nodedump')

request.get("http://pubapi.cryptsy.com/api.php?method=marketdatav2",function(err,res)
{
    var data
    console.log( "Data received." );
    data = JSON.parse(res.body)
    console.log( "Data parsed."   );
    data = nodedump.dump(data)
    console.log( "Data dumped."   ); 
    console.log( data )
})

Aby sprawdzić, czy to problem ze stosem rekurencyjnym, uruchomiłem następny kod z parametrem --stack-size = 60000

var depth = 0;

(function recurse() {
    // log at every 500 calls
    (++depth % 500) || console.log(depth);
    recurse();
})();

i mam

264500 
Segmentation fault

Potem uruchomiłem kod, który daje mi FATAL ERROR: CALL_AND_RETRY_LAST Alokacja nie powiodła się - proces nie ma pamięci o tym samym parametrze --stack-size = 60000 i nie ma go Segmentation fault.

Stwierdzam więc, że CALL_AND_RETRY_LASTnie ma nic wspólnego z rozmiarem stosu rekurencyjnego.

Jak mogę rozwiązać ten problem? Uważam, że na moim komputerze jest wystarczająca ilość wolnej pamięci, aby pomyślnie zakończyć to zadanie.

Istnieją podobne pytania na temat przepływu stosu, ale żadne z tych pytań nie dotyczy CALL_AND_RETRY_LASTtego, dlatego stworzyłem osobne pytanie.


3
Twój kod działa dla mnie dobrze w Node.js 0.10.28. Zajęło 1200 MB pamięci wirtualnej i wydrukowało niewiarygodną ilość śmieci na ekranie, ale wydawało się, że „działa”.
John Zwinck

1
Śmieci są dokładnie tym, czego chciałem. Złe jest to, że węzeł 0.10. * Nie obsługuje generatorów harmonii, dlatego nie mogę go używać do tych celów.
user619271

Odpowiedzi:


112

Jeśli spojrzysz na źródło: github / v8 , wygląda na to, że próbujesz zarezerwować bardzo duży obiekt. Z mojego doświadczenia wynika, że ​​próbujesz sparsować ogromny obiekt JSON, ale kiedy próbuję parsować twój wynik za pomocą JSON i węzeł0.11.13, po prostu działa dobrze.

Nie potrzebujesz więcej --stack-size, potrzebujesz więcej pamięci: --max_new_space_sizei / lub --max_old_space_size.

Jedyną wskazówką, jaką mogę ci podać poza, jest próba użycia innego parsera JSON i / lub próba zmiany formatu wejściowego na wiersz JSON zamiast tylko JSON.


10
Dziękuję Ci bardzo! Zdefiniowanie --max_old_space_size = 2000000, co według mnie oznacza, że ​​~ 2 GB rozwiązało mój problem. Różnicowanie - max_new_space_size nie wydaje się mieć żadnego efektu.
user619271,

Zajrzałem także do źródła v8, ale w ogóle nie zrozumiałem, co się tam dzieje. Więc moje szanse na rozwiązanie tego bez twojej pomocy są prawdopodobnie zerowe. Dziękuję jeszcze raz.
user619271

1
@ theWanderer4865 co masz na myśli mówiąc „spróbuj zmienić format wejściowy na linię JSON zamiast tylko JSON.”? Czy możesz prosić o opracowanie? Dziękuję Ci.
titusmagnus

16
@ user619271 --max_old_space_size = 2048 to 2 GB
Ponadczasowy

1
Haha .. @Timeless
technophyle

51
$ sudo npm i -g increase-memory-limit

Uruchom z głównej lokalizacji swojego projektu:

$ increase-memory-limit

To narzędzie dołączy --max-old-space-size = 4096 do wszystkich wywołań węzłów w plikach node_modules / .bin / *.


Wersja Node.js> = 8 - UWAGA DOTYCZĄCA DEPRECACJI

Od wersji NodeJs 8.0.0 można użyć tej opcji --max-old-space-size. NODE_OPTIONS = opcje ...

$ export NODE_OPTIONS=--max_old_space_size=4096

cześć, @ sol-ibit. Co oznacza argument 4096?
estebanpdl,

1
Cześć @estebanpdl, Rozwiązaniem do uruchomienia aplikacji Node.js ze zwiększoną pamięcią jest rozpoczęcie procesu z dodatkową flagą V8: --max-old-space-size. Musisz dodać żądaną wielkość pamięci w megabajtach. Następujące polecenie uruchomi aplikację z limitem pamięci 4 GB.
sol404

1
Ustawienie zmiennej za pomocą export NODE_OPTIONS=--max_old_space_size=4096zrobiło dla mnie lewę! Dzięki!
Tarator

46

Aby rozwiązać ten problem, musisz uruchomić aplikację, zwiększając limit pamięci za pomocą opcji --max_old_space_size. Domyślnie limit pamięci Node.js wynosi 512 MB.

node --max_old_space_size=2000  server.js 

5
Czy istnieje przewodnik krok po kroku, jak to zrobić, proszę? Gdzie wkleić ten wierny kod: node --max_old_space_size=2000 server.js
Pan Benedykt

@ Mr.Benedict robisz to po uruchomieniu aplikacji.
easymoden00b

2
węzeł - max_old_space_size = 2048 server.js ... jest bardziej odpowiedni ... działa dzięki
danday74

1
Mam aplikację React w Google Cloud. W jaki sposób mogę to zrobić? Czy ktoś może poprowadzić?
Shubham Kushwah

1
@ easymoden00b Nie node server.js, raczej npm start. W jaki sposób mogę to zrobić?
Shubham Kushwah

30

Odkryłem, że max_new_space_sizenie jest to opcja w węźle 4.1.1 i max_old_space_sizesam nie rozwiązał mojego problemu. Dodaję do mojego shebang i kombinacja tych wydaje się działać:

#!/usr/bin/env node --max_old_space_size=4096 --optimize_for_size --max_executable_size=4096 --stack_size=4096

[EDYCJA]: 4096 === 4 GB pamięci, jeśli w urządzeniu brakuje pamięci, możesz wybrać mniejszą ilość.

[AKTUALIZACJA]: Odkryłem również ten błąd podczas uruchamiania chrząka, który wcześniej był uruchamiany w następujący sposób:

./node_modules/.bin/grunt

Po zaktualizowaniu polecenia do następującego przestało występować błędy pamięci:

node --max_old_space_size=2048 ./node_modules/.bin/grunt 

4
Dodałem --max_old_space_size = 8192, to nadal nie rozwiązało problemu, ale zawiesiło mój komputer :(
Dhyey

Zmniejszyłem ilość pamięci w przykładzie z 8 Gb do 4 Gb, dzięki za opinie.
jfunk

28

Uwaga: patrz ostrzeżenie w komentarzach na temat tego, jak może to wpłynąć na aplikacje elektronowe.

Od wersji 8.0 dostarczonej w sierpniu 2017 roku zmienna środowiskowa NODE_OPTIONS ujawnia tę konfigurację (patrz NODE_OPTIONS wylądowało w wersji 8.x! ). W artykule dozwolone są tylko opcje umieszczone na białej liście w źródle (uwaga: nie aktualny link!), W tym "--max_old_space_size". Zauważ, że tytuł tego artykułu wydaje się nieco mylący - wygląda na to, że NODE_OPTIONS już istniał, ale nie jestem pewien, czy ujawnił tę opcję.

Wstawiłem więc .bashrc:
export NODE_OPTIONS=--max_old_space_size=4096


Słowo ostrzeżenia: nie ustawiaj tego jako zmiennej środowiskowej na komputerze z systemem Windows. Łamie wszystko . Złamał GitKraken, Slack, instalator VS2017 (który jest oparty na chromie), rozszerzenia VS2017 związane z platformą Azure, a nawet element menu „Rozszerzenia i aktualizacje” w VS2017.
Roman Starkov,

Spójrz na github.com/electron/electron/issues/12695 - wygląda na to, że Electron nie ulegnie awarii z NODE_OPTIONS w 2.0.3 - ale ustawiłem NODE_OPTIONS za pomocą smartcd tylko w określonych katalogach projektów, aby uniknąć tego problemu github.com/cxreg / smartcd
Ben Creasy

Ach, to prawdopodobnie wyjaśnia, dlaczego Discord i VS Code nie uległy zmianie.
Roman Starkov,

1
Jak to zrobić na komputerze z systemem Windows?
Mahmoud Ezzat

16

increase-memory-limitModuł został przestarzałe teraz. Od wersji Node.js 8.0 dostarczonej w sierpniu 2017 r. Możemy teraz używać NODE_OPTIONSzmiennej env do ustawiania max_old_space_sizeglobalnego.

export NODE_OPTIONS=--max_old_space_size=4096

Ref URL: https://github.com/endel/increase-memory-limit


Gdzie to ustawiasz? Korzystam z kompilacji Azure DevOps i kompilacje kończą się niepowodzeniem w agentach Windows
int-i

Aby uniknąć różnicy między platformami, zainstaluj cross-envmoduł globalnie i uruchom na terminalu takie polecenie -cross-env PORT=8000 node --max-old-space-size=4096 server.js
Ali David

Kompilacje Azure Devops są uruchamiane na agentach MS w chmurze, nie ma żadnych konsol do ich wykonania. Znalazłem inny sposób na osiągnięcie tego za pomocą PowerShell. Dodano go jako odpowiedź tutaj.
int-i

13

Tylko wariant powyższych odpowiedzi.

Próbowałem powyżej polecenia węzła prosto w górę bez powodzenia, ale sugestia z tego problemu Angular CLI zadziałała dla mnie - tworzysz skrypt Node w swoim package.jsonpliku, aby zwiększyć pamięć dostępną dla Node podczas uruchamiania kompilacji produkcyjnej.

Więc jeśli chcesz zwiększyć pamięć dostępną dla Node do 4 gb ( max-old-space-size=4096), twoja komenda Node to node --max-old-space-size=4096 ./node_modules/@angular/cli/bin/ng build --prod. (zwiększ lub zmniejsz ilość pamięci również w zależności od potrzeb - 4 GB działało dla mnie, ale możesz potrzebować więcej lub mniej). Dodałbyś go do sekcji „scripts” pakietu.json w następujący sposób:

"prod": "node --max-old-space-size=4096 ./node_modules/@angular/cli/bin/ng build --prod"

Byłby zawarty w obiekcie skryptów wraz z innymi dostępnymi skryptami - np .:

"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "prod": "node --max-old-space-size=4096./node_modules/@angular/cli/bin/ng build --prod"
}

I uruchamiasz go, dzwoniąc npm run prod(możesz potrzebować uruchomić, sudo npm run prodjeśli jesteś na komputerze Mac lub Linux).

Zauważ, że może istnieć podstawowy problem, który powoduje, że Węzeł potrzebuje więcej pamięci - to nie rozwiązuje tego problemu, ale przynajmniej daje Węzłu pamięć potrzebną do wykonania kompilacji.


6

Moje działające rozwiązanie to:

  • Zainstaluj cross-env
    npm install --save-dev cross-env lub npm install -g cross-env.
  • Plik package.jsondodaj nowy skrypt kompilacji
    np
    ... "build:prod:ios": "cross-env NODE_OPTIONS='--max-old-space-size=8192' ionic cordova build ios --prod --release" ...
  • Użyj tego polecenia, aby zbudować następnym razem.
    npm run build:prod:ios

  • Problem rozwiązany.


1

Straciłem kilka dni z tym problemem ... dopóki nie znalazłem, że w jakimś pliku importowałem jeden plik statyczny, plik zbudowany. To sprawia, że ​​kompilacja nigdy się nie kończy. Coś jak:

import PropTypes from "../static/build/prop-types"; 

Naprawienie prawdziwego źródła rozwiązało cały problem.

Udostępnianie mojego rozwiązania. :)


2
czy mógłbyś bardziej wyjaśnić swoje rozwiązanie? Mam ten sam problem i powoduje awarię mojej aplikacji. Przez pierwsze kilka minut działania aplikacji wszystko działa dobrze, ale w końcu kończy się awaria spowodowana brakiem pamięci. Ale w tym okresie Sequelize działa dobrze.
Porlune

1
Stało się tak, że mój IDE (WebStorm) automatycznie uwzględnił WBUDOWANE js w moich źródłach ... kiedy jeden plik (w moich źródłach) został zmieniony, buduje wszystkie pliki w nowe wyjście js. Ale jeśli moje źródła zawierają odniesienia do skompilowanych plików, kompilacja nigdy się nie kończy. Sprawdź, który plik zawiera nieprawidłowy plik.
Tiago Gouvêa

1

Widziałem ten problem, gdy tworzyłem pakiet dla native-reagujących. Rzeczy, które próbowałem i nie działałem:

  1. Zwiększenie node --max_old_space_size, co ciekawe, działało lokalnie dla mnie, ale nie powiodło się w przypadku Jenkins i nadal nie jestem pewien, co poszło nie tak z Jenkins
  2. Niektóre wymienione miejsca obniżyły wersję węzła do wersji 6.9.1 i to też nie działało dla mnie. Chciałbym po prostu to tutaj umieścić, ponieważ może ci się to przydać.

To działało dla mnie: importowałem naprawdę duży plik w kodzie. Sposób, w jaki to rozwiązałem, polegał na umieszczeniu go na ignoreliście w .babelrccoś takiego:

{
    "presets": ["react-native"],
    "plugins": ["transform-inline-environment-variables"],
    "ignore": ["*.json","filepathToIgnore.ext"]
}

Był to .jsplik, który tak naprawdę nie wymagał transpilacji, a dodanie go do listy ignorowanych pomogło.


1

ten błąd występuje, gdy wymagana pamięć przydzielona do wykonania jest mniejsza niż pamięć wymagana do uruchomienia procesu. Domyślnie rozmiar pamięci węzła wynosi 512 MB, aby go zwiększyć, należy wpisać następujące polecenie:

node --max-old-space-size= <NewSize> <fileName>

1
jaka jest tutaj nazwa pliku?
Rashedul.Rubel

1

Napotkałem ten problem w trybie jonowym i wypróbowałem wiele rozwiązań, ale rozwiązałem to, uruchamiając to.

Dla MAC: węzeł - max-old-space-size = 4096 / usr / local / bin / ionic cordova build android --prod

W systemie Windows: węzeł - max-old-space-size = 4096 / Users / {your user} / AppData / Roaming / npm / node_modules / ionic / bin / ionic cordova build windows --prod


1
npm install -g increase-memory-limit

Zwiększ limit pamięci

LUB

  1. Przejdź do folderu% appdata% -> npm lub C:\Users\{user_name}\AppData\Roaming\npm
  2. Otwórz ng.cmd w swoim ulubionym edytorze
  3. Dodaj --max_old_space_size=8192do IFi ELSEzablokuj

plik ng.cmd wygląda teraz tak po zmianie:

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

1

Na komputerze z systemem Windows uruchom polecenie poniżej

ustaw NODE_OPTIONS = - max_old_space_size = 4096



0

Każdy, kto otrzymuje ten błąd dzięki potokom kompilacji platformy Azure, spróbuj wykonać poniższy krok, aby zmienić zmienną środowiskową agenta kompilacji

Dodaj Azure build pipeline task-> Azure powershell script:Inlinescriptprzed Kompiluj z poniższymi ustawieniami

- task: AzurePowerShell@3
  displayName: 'Azure PowerShell script: InlineScript'
  inputs:
    azureSubscription: 'NYCSCA Azure Dev/Test (ea91a274-55c6-461c-a11d-758ef02c2698)'
    ScriptType: InlineScript
    Inline: '[Environment]::SetEnvironmentVariable("NODE_OPTIONS", "--max_old_space_size=16384", "Machine")'
    FailOnStandardError: true
    azurePowerShellVersion: LatestVersion

0

#! / usr / bin / env node - max-old-space-size = 4096 w ionic-app-scripts.js nie działa

Ale po modyfikacji: działał następujący plik

node_modules / .bin / ionic-app-scripts.cmd

Poprzez dodanie:

@IF EXIST "% ~ dp0 \ node.exe" ("% ~ dp0 \ node.exe" "% ~ dp0 .. @ ionic \ app-scripts \ bin \ ionic-app-scripts.js"% *) ELSE ( @SETLOCAL @SET PATHEXT =% PATHEXT:;. JS; =;% node --max_old_space_size = 4096 "% ~ dp0 .. @ ionic \ app-scripts \ bin \ ionic-app-scripts.js"% *)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.