Node.js montón de memoria

246

Hoy ejecuté mi script para la indexación del sistema de archivos para actualizar el índice de archivos RAID y después de 4h se bloqueó con el siguiente error:

[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

El servidor está equipado con 16 gb de RAM y 24 gb de intercambio SSD. Dudo mucho que mi script supere los 36 gb de memoria. Al menos no debería

El script crea un índice de archivos almacenados como Matriz de objetos con metadatos de archivos (fechas de modificación, permisos, etc., sin grandes datos)

Aquí está el código completo del script: http://pastebin.com/mjaD76c3

Ya he experimentado problemas de nodos extraños en el pasado con este script que me obligó, por ejemplo. dividir el índice en varios archivos ya que el nodo fallaba cuando trabajaba en archivos tan grandes como String. ¿Hay alguna manera de mejorar la administración de memoria de nodejs con grandes conjuntos de datos?

Lapsio
fuente

Respuestas:

315

Si no recuerdo mal, hay un límite estándar estricto para el uso de memoria en V8 de alrededor de 1.7 GB, si no lo aumenta manualmente.

En uno de nuestros productos, seguimos esta solución en nuestro script de implementación:

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

También habría un nuevo comando de espacio, pero como leí aquí: a-tour-of-v8-garbage-collection, el nuevo espacio solo recopila los datos a corto plazo recién creados y el espacio antiguo contiene todas las estructuras de datos referenciadas que deberían estar en Su caso la mejor opción.

Felix
fuente
De la misma manera, esta configuración es para nodejs independientemente en el marco. @ Simer
Felix
Estoy desarrollando con angular 4 y obtengo el mismo problema, ¿cuál debería ser el archivo yourFile.js para la aplicación angular?
Vikram
@VikramSingh ¿está utilizando ng serveo distribuye el resultado de ng buildla carpeta / dist por otro servidor web como express? Pero si su proyecto Angular está usando más de la memoria estándar de 1.7GB, ¿quizás tenga un problema arquitectónico en su aplicación? Parece que está utilizando el entorno de desarrollo con nmp start, tal vez esta sea una solución para ello github.com/mgechev/angular-seed/issues/2063
Felix
Estoy usando ng build con angular cli y aot (carpeta dist)
Vikram
2
index, js file @Techdive que utiliza para iniciar el servidor
Basit
77

En caso de que alguien se encuentre con esto en un entorno donde no puede establecer las propiedades del nodo directamente (en mi caso, una herramienta de compilación):

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

Puede configurar las opciones de nodo utilizando una variable de entorno si no puede pasarlas en la línea de comando.

Kamiel Wanrooij
fuente
¿Puede explicar a qué se refiere cuando dice "... establezca las opciones de nodo utilizando una variable de entorno ..."?
Keselme
66
@Keselme Una variable de entorno es una variable que se ha establecido en el servidor desde la cual todos los procesos pueden leer los datos. Abra una terminal SSH en su servidor y escriba: MY_VAR = hola, luego escriba: echo $ MY_VAR. Verá que imprime "hola" en la terminal. Acaba de establecer una variable de entorno y volver a leerla.
Rob Evans el
trabajó en Ubuntu 18.04, acabo de agregar el comando de exportación a mi archivo bashrc
Rahal Kanishka
76

Si desea aumentar el uso de memoria del nodo globalmente, no solo un script, puede exportar una variable de entorno, como esta:
export NODE_OPTIONS=--max_old_space_size=4096

Entonces no necesita jugar con archivos cuando ejecuta compilaciones como npm run build.

Maksim Luzik
fuente
1
Como conveniencia adicional, agregue al perfil bash_profile o zsh.
Tropicalrambler
24

Encontré este problema al intentar depurar con VSCode, por lo que solo quería agregar esto, así es como puede agregar el argumento a su configuración de depuración.

Puede agregarlo a la runtimeArgspropiedad de su configuración en launch.json.

Ver ejemplo a continuació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"
        ]
    }
]}
Astr-o
fuente
21

Estos son algunos valores de marca para agregar información adicional sobre cómo permitir más memoria cuando inicia su servidor de nodo.

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 
Nicholas Porter
fuente
¿Se puede seguir aumentando en potencias de 2? ¿debería uno configurarlo más grande que la memoria del sistema? si no, ¿cuál es una buena relación de memoria del sistema a tamaño máximo de espacio antiguo?
Harry Moreno
3
@HarryMoreno En realidad, puede poner cualquier valor numérico que desee. No tiene que estar en el poder de 2. Sin embargo, no estoy seguro sobre la relación. Es solo un límite máximo, no usará toda la memoria. Simplemente lo establecería tan alto como sea necesario y luego reduciría si fuera necesario.
Nicholas Porter
Voy a probar el sistema ram - 1gb. Suponiendo que esta vm es solo para ejecutar esta aplicación de nodo.
Harry Moreno
2
@HarryMoreno Una buena relación de memoria del sistema a tamaño máximo de espacio antiguo depende completamente de qué más se esté ejecutando en su máquina. Puede aumentarlo en potencias de dos, o puede usar cualquier número. Puede configurarlo más grande que la memoria del sistema, pero tendrá problemas de intercambio.
Gigimoi
20

Estaba luchando con esto incluso después de configurar --max-old-space-size.

Luego me di cuenta de la necesidad de poner opciones --max-old-space-size antes del script de karma.

También es mejor especificar ambas sintaxis: max-old-space-size y --max_old_space_size mi script para karma:

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

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

duchuy
fuente
55
"es mejor especificar ambas sintaxis --max-old-space-size y --max_old_space_size " - no necesita hacer esto, son sinónimos. De nodejs.org/api/cli.html#cli_options : "Todas las opciones, incluidas las opciones V8, permiten que las palabras se separen con guiones (-) o guiones bajos (_)".
ZachB
66
max-ejecutable-size se eliminó y termina en un error cuando se usa: github.com/nodejs/node/issues/13341
crashbus el
Tuve que cortarlo --max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizey funcionó
Sergey Pleshakov
16

Tuve un problema similar al hacer la construcción angular AOT. Los siguientes comandos me ayudaron.

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

Fuente: https://geeklearning.io/angular-aot-webpack-memory-trick/

Chandru
fuente
1
Cheers funcionó para mí, puede ser necesariosudo npm -g install increase-memory-limit --unsafe-perm
Leo
11

fwiw, encontrar y arreglar un cerdo de memoria con algo como memwatch podría ayudar.

NathanQ
fuente
10

Pasos para solucionar este problema (en Windows):

  1. Abra el símbolo del sistema y escriba %appdata%presione enter
  2. Navegue a %appdata%> carpeta npm
  3. Abre o edita ng.cmden tu editor favorito
  4. Agregar --max_old_space_size=8192al bloque IF y ELSE

Su node.cmdarchivo se ve así después del cambio:

@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" %*
)
Umang Patwa
fuente
Esto es específico de Windows. El OP no mencionó nada sobre Windows.
Dan Dascalescu
@DanDascalescu Respuesta actualizada. Gracias por avisar
Umang Patwa
6

Se puede usar la siguiente variable de entorno:

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

Otra nota: console.log()también consume memoria en el terminal.

Solo traté de comentar el console.log () en la terminal. porque eso también tomará memoria.

Amar Powar
fuente
66
¿Es esta una respuesta o comentario a alguna respuesta? Hay muchas respuestas conNODE_OPTIONS= --max-old-space-size=somesize
barbsan
5

si desea cambiar la memoria globalmente para el nodo (windows) vaya a la configuración avanzada del sistema -> variables de entorno -> nueva variable de usuario

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096
Ahmed Aboud
fuente
4

Solo quiero agregar que en algunos sistemas, incluso aumentando el límite de memoria del nodo --max-old-space-size, no es suficiente y hay un error del sistema operativo como este:

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

En este caso, probablemente se deba a que alcanzó el mmap máximo por proceso.

Puede verificar max_map_count ejecutando

sysctl vm.max_map_count

y aumentarlo corriendo

sysctl -w vm.max_map_count=655300

y corríjalo para que no se reinicie después de reiniciar agregando esta línea

vm.max_map_count=655300

en el /etc/sysctl.confarchivo

Consulta aquí para más información.

Un buen método para analizar el error es ejecutar el proceso con strace

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

Recientemente me enfrenté a este mismo problema y me encontré con este hilo, pero mi problema era con la Reactaplicación. A continuación, los cambios en el comando de inicio de nodo resolvieron mis problemas.

Sintaxis

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

Ejemplo

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

¿Por qué el tamaño es 16000 en max-old-space-size?

Básicamente, varía según la memoria asignada a ese subproceso y la configuración de su nodo.

¿Cómo verificar y dar el tamaño correcto?

Esto es básicamente permanecer en nuestro motor v8. El siguiente código le ayuda a comprender el tamaño de almacenamiento dinámico de su motor de nodo local v8.

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

Acabo de enfrentar el mismo problema con mi instancia EC2 t2.micro que tiene 1 GB de memoria.

Resolví el problema creando un archivo de intercambio usando esta url y establecí la siguiente variable de entorno.

export NODE_OPTIONS=--max_old_space_size=4096

Finalmente el problema se ha ido.

Espero que sea útil para el futuro.

Bat-Orshikh Baavgaikhuu
fuente
1

En caso de que pueda ayudar a las personas que tienen este problema al usar aplicaciones de nodejs que producen un registro pesado, un colega resolvió este problema conectando las salidas estándar a un archivo.

Adrien Joly
fuente
1

Si está intentando iniciar no nodesolo, sino algún otro software, por ejemplo webpack, puede usar la variable de entorno y el cross-envpaquete:

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

Para la agrupación angular de proyectos, he agregado la siguiente línea a mi archivo pakage.json en la sección de secuencias de comandos .

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

Ahora, para agrupar mi código, uso en npm run build-prodlugar deng build --requiredFlagsHere

¡espero que esto ayude!

rgantla
fuente
0

Nodo de actualización a la última versión. Estaba en el nodo 6.6 con este error y actualicé a 8.9.4 y el problema desapareció.

Richard Frank
fuente
0

En mi caso, había ejecutado la npm installversión anterior del nodo, después de algún día actualicé la versión del nodo y la memoria RAM npm installpara algunos módulos. Después de esto recibí este error. Para solucionar este problema, eliminé la carpeta node_module de cada proyecto y volví a ejecutar npm install.

Espero que esto pueda solucionar el problema.

Nota: Esto estaba sucediendo en mi máquina local y se solucionó solo en la máquina local.

Gampesh
fuente
0

Este comando funciona perfectamente. Tengo 8 GB de RAM en mi computadora portátil, así que configuré size = 8192. Se trata de ram y también necesita establecer el nombre del archivo. Corro acumulación de ejecución NPM comando Es por eso que he usado build.js .

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

En mi caso, actualicé la versión de node.js a la última y funcionó de maravilla.

Angela Rana
fuente
Hola Angela y bienvenidos a SO! ¿Podría especificar la versión exacta de Node.js a la que actualizó para futuros lectores? ¡Gracias!
kant312
Actualicé a la última versión de LTS: 12.18.0
Angela Rana