Hur man åtgärdar ”JavaScript Heap of Memory Error”

JavaScript behåller sin position som ett av de mest använda programmeringsspråken, främst tack vare dess anpassningsförmåga. För att möjliggöra körning av JavaScript utanför webbläsarens sfär, behöver utvecklare implementera Node.js, en plattformsoberoende körmiljö.

Ett vanligt problem som uppstår i samband med JavaScript Node.js-projekt är felet relaterat till brist på minne i JavaScript-högen.

Detta minnesbristfel i JavaScript-högen indikerar att det standardminne som tilldelats av systemet inte är tillräckligt för att hantera ett resurskrävande projekt.

Vid detta fel kommer ditt program att krascha, och följande felmeddelande visas:

FATALT FEL: CALL_AND_RETRY_LAST Minnesallokering misslyckades – JavaScript-högen saknar minne

Alternativt kan följande felmeddelande dyka upp:

Allvarligt fel: Ogiltig allokering av tabellstorlek misslyckades – javascript-högen saknar minne

Orsaker bakom JavaScript-högen full av minnesfel

  • Förekomst av stora datastrukturer: Användning av stora datastrukturer, som matriser, kräver mycket minne, vilket i sin tur kan leda till minnesfel.

Här följer ett exempel på en stor datastruktur med en miljard element:

let array = [];

for (let i = 0; i < 1000000000; i++) {

  array.push(i);

}
  • Bristfällig minneshantering: När applikationen växer är det viktigt att frigöra minne som inte längre används.

Här är ett exempel på en funktion som resulterar i minnesläcka:

let array = [];

setInterval(function() {

  array.push(new Array(1000000).join("x"));

}, 1000);
  • Oändliga loopar: Sådan kod fortsätter att köras i all oändlighet, eftersom det saknas ett avslutande villkor.

Ett exempel på en oändlig loop:

while (true) {

    console.log(1);

}

Oändliga loopar kan orsaka minnesfel då de snabbt förbrukar minne.

  • Rekursiva funktioner: En rekursiv funktion anropar sig själv, direkt eller indirekt, för att repetera instruktioner tills ett villkor är uppfyllt. Om dessa funktioner inte är korrekt designade kan de leda till minnesläckor och minnesfel.
  • Överdriven mängd objekt i kod: Om din kod hanterar många stora objekt kan den totala minnesanvändningen leda till överbelastning.

Lösning på JS-högen full av minnesfel

Det här felet kan inträffa på operativsystem som Windows, macOS och Linux (Ubuntu). Lyckligtvis kan det lösas oavsett vilket operativsystem du använder.

#1. Lösning på JavaScript-högen full av minnesfel i Windows

Steg 1: Öppna Startmenyn och sök efter ”Avancerade systeminställningar”.

Steg 2: Klicka på ”Miljövariabler” längst ner till vänster i dialogrutan.

Steg 3: Välj ”Ny” under antingen ”Användarvariabler” eller ”Systemvariabler”. Det första alternativet påverkar endast aktuellt användarkonto, medan det andra påverkar hela systemet.

Steg 4: Två fält kommer att visas. I ”Variabelnamn” skriver du in `NODE_OPTIONS` och i ”Variabelvärde” anger du `–max-old-space-size=4096`. Detta steg tilldelar 4 GB virtuellt minne till Node.js. Du kan öka detta värde, till exempel till 8 GB, genom att ange `–max-old-space-size=8192`.

Steg 5: Klicka på ”OK”, sedan ”Använd” och slutligen ”OK” för att spara inställningarna.

Du kan även använda Windows PowerShell för att åtgärda felet. Öppna terminalen i Windows och ange följande kommando:

env:NODE_OPTIONS="--max-old-space-size=4096"

En tillfällig lösning är att köra det här kommandot innan du startar din applikation:

set NODE_OPTIONS=--max-old-space-size=4096

#2. Lösning på JavaScript-högen full av minnesfel i Linux

  • Steg 1: Identifiera felets källa. Granska konsolloggarna för att bestämma vilka kodrader eller filer som orsakar felet.
  • Steg 2: Ange en miljövariabel som tilldelar minne till Node.js genom att använda följande kommando:
export NODE_OPTIONS=--max-old-space-size=4096

Dessa steg kommer att tilldela 4 GB virtuellt minne till Node.js. Om felet kvarstår kan du fördubbla minnesstorleken.

För att till exempel tilldela 8 GB virtuellt minne kan du använda följande kommando:

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

#3. Lösning på JavaScript-högen full av minnesfel i macOS

Du kan åtgärda felet i macOS på ett liknande sätt som i Linux. Följ dessa steg:

  • Steg 1: Identifiera felkällan genom att granska konsolloggarna för att se vilka kodrader eller filer som orsakar felet.
  • Steg 2: Skapa en miljövariabel som anger det virtuella minnet som tilldelas Node.js med följande kommando:
export NODE_OPTIONS=--max-old-space-size=4096

Dessa steg tilldelar 4 GB virtuellt minne till Node.js. Om felet kvarstår kan du öka minnesstorleken genom att fördubbla.

Om du till exempel vill tilldela 8 GB virtuellt minne kan du använda följande kommando:

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

Öka minnet under NPM-installation

De lösningar som hittills beskrivits fungerar för fel som uppstår när du kör en Node.js-applikation. Det är också möjligt att tilldela virtuellt minne för att hantera minnesfel under installation av JavaScript-paket. Använd detta kommando:

node --max-old-space-size=4096 (which npm) install

Obs! Du kan öka den virtuella minnesallokeringen med 1 GB, 2 GB, 3 GB eller 4 GB. Minnesstorleken måste anges i MB. Undvik att tilldela hela maskinens minne till Node.js, eftersom det kan leda till att programmet kraschar. Om din dator har 16 GB RAM kan du med fördel tilldela upp till 8 GB till Node.js.

Förebyggande av JavaScript-högen full av minnesfel

Vi har diskuterat hur man åtgärdar minnesbristfel i JavaScript-högen. Lyckligtvis kan du vidta förebyggande åtgärder för att undvika att felet inträffar under körning av JavaScript-kod. Här är några bästa metoder:

#1. Dela upp data i mindre bitar

Om du har ett Node.js-program som importerar stora datamängder från stora CSV-filer genom ETL-processen (Extract – Transform – Load), kan det leda till krascher. Om du använder MongoDB kan du lösa detta med följande kommando:

split -l 1000000 users.csv

Det här kommandot instruerar Node.js att dela en fil som heter ”users” i flera filer med 1 000 000 användare per fil. Flaggan `-l` indikerar att filen ska delas baserat på antalet rader.

#2. Övervaka minnesanvändning

Du kan använda en minnesprofilerare för att identifiera minnesläckor i din kod. Du kan kombinera Node.js inbyggda minnesfunktioner med ChromeDevTools för att uppnå detta. Dessa verktyg kan hitta och åtgärda problem i koden.

Det finns också externa verktyg som Datadog, New Relic och AppDynamics för att övervaka applikationens prestanda och vidta åtgärder. Du kan även använda metoden `process.memoryUsage()` i Node.js för att granska minnesanvändningen.

#3. Undvik minnesläckor

Minnesläckor uppstår när Node.js-applikationen behåller referenser till objekt som den inte längre behöver. Om dessa objekt inte samlas in av skräpsamlaren kommer minnesanvändningen öka över tid.

För att undvika minnesläckor kan du bland annat undvika globala variabler i din kod, undvika att blockera I/O-operationer och använda nyckelorden `let` och `const` när du deklarerar variabler istället för `var`.

#4. Arbetsprocesser

Om Node.js körs på en maskin med begränsat minne, till exempel Raspberry Pi, är risken för minnesfel högre. Du kan använda en huvudprocess och gruppera andra processer som arbetare. Så snart huvudprocessen upptäcker att systemet får slut på minne, kan den avsluta processen och delegera uppgiften till en annan process som inte är överbelastad.

#5. Uppdatera hårdvara

Om ökad minnesallokering och de metoder som beskrivits för att förebygga minnesfel inte löser problemet, kan en uppdatering av hårdvaran behövas. Node.js kan köras med 512 MB RAM. Applikationen kräver dock mer RAM-minne när den växer.

En ökning av antalet processorer kan också förbättra minnesallokeringen. Med två eller fler processorer kan applikationen använda arbetstrådar för CPU-intensiva uppgifter som kryptografi och bildbehandling.

Vanliga frågor

Vad orsakar JavaScript Heap Out of Memory Error?

Flera faktorer kan orsaka detta fel:
1. Minnesläckor
2. Oändliga loopar
3. För många objekt i ett projekt
4. Stora datastrukturer

Är JavaScript-högen full av minnesfel lösbart?

Ja. Du kan lösa felet genom:
1. Att öka det virtuella minnet som tilldelas Node.js
2. Eliminera minnesläckor
3. Optimera koden
4. Uppgradera hårdvaran

Hur löser man minnesbristfel i en React-app?

React är ett populärt JavaScript-bibliotek. Öppna `package.json`-filen och lägg till följande rader i skriptsektionen:

"scripts": {

  "start": "react-scripts --max_old_space_size=4096 start",

  "build": "react-scripts --max_old_space_size=4096 build",

  "test": "react-scripts test",

  "eject": "react-scripts eject"

}

Avslutning

Många utvecklare är bekanta med buggar och kodfel men inte med runtime-fel under körning av Node.js-program. Lyckligtvis kan minnesbristfel åtgärdas. Vi har beskrivit vad minnesbristfel i JavaScript-högen är, hur det kan åtgärdas och hur det kan undvikas i framtida Node.js-projekt.

Du kan läsa vidare om hur du kan undvika vanliga JavaScript-fel.