Node.js recomienda "max-old-space-size"

95

Tengo problemas para entender cómo actúa Node.js en función del parámetro max-old-space-size.

En mi caso, por ejemplo, estoy ejecutando dos t2.smallinstancias de AWS (2 GB de RAM).

No estoy seguro de por qué, pero configuré max-old-space-size=4096(4GB). ¿Qué hace el nodo en este caso? ¿Esta configuración podría provocar una posible falla en la asignación de memoria?

¿Cómo puedo determinar el valor correcto de max-old-space-sizesegún los recursos del servidor?

Mi aplicación aumenta constantemente el uso de la memoria y estoy tratando de entender todo sobre los componentes internos de los nodos.

Borjante
fuente
8
Estoy agregando un comentario ahora que veo que esto se está volviendo mucho más silencioso. Me tomó una semana completa darme cuenta de que mi aplicación NodeJS no tenía pérdida de memoria, pero que el recolector de basura nunca se activó. Tenga esto en cuenta en sistemas con poca memoria como t2.micro o t2.small. El servidor se bloqueará debido a la RAM no disponible.
Borjante
¿Había alguna manera de hacer que el recolector de basura se activara?
ZG101
@Borjante, ¿por qué no estaba funcionando el recolector de basura?
divino
2
El tamaño de espacio antiguo máximo configurado tenía un límite más alto que la cantidad total de RAM que tenía la máquina.
Borjante

Respuestas:

129

El "espacio antiguo" es la sección más grande y configurable del montón administrado (también conocido como recolección de basura) de V8 (es decir, donde viven los objetos JavaScript), y la --max-old-space-sizebandera controla su tamaño máximo. A medida que el consumo de memoria se acerca al límite, V8 dedicará más tiempo a la recolección de basura en un esfuerzo por liberar memoria no utilizada.

Si el consumo de memoria del montón (es decir, objetos en vivo que el GC no puede liberar) excede el límite, V8 bloqueará su proceso (por falta de alternativa), por lo que no querrá establecerlo demasiado bajo. Por supuesto, si lo establece demasiado alto, entonces el uso adicional del montón que permitirá V8 podría hacer que su sistema general se quede sin memoria (y que intercambie o elimine procesos aleatorios, por falta de alternativa).

En resumen, en una máquina con 2 GB de memoria probablemente establecería --max-old-space-sizealrededor de 1,5 GB para dejar algo de memoria para otros usos y evitar el intercambio.

jmrk
fuente
4
Eso es exactamente lo que esperaba obtener como respuesta, describiendo el caso límite en el que el sistema o el nodo se quedan sin memoria.
Borjante
2
@jmrk: Parece que tiene toda la razón, pero cuando estoy usando 2GB de RAM y 4GB de intercambio y configuro "--max-old-space-size" en 4GB, el proceso de nodo consume toda la memoria RAM y se atasca en 1.9GB. La pregunta está aquí "¿Por qué el intercambio es evitar su uso?" (Node versión 8.11.1)
Manish Trivedi
1
La bandera debería anular cualquier otra cosa. Vuelva a comprobar si hay errores tipográficos.
jmrk
2
Desde d8 --help:--max-old-space-size (max size of the old space (in Mbytes))
jmrk
12

Actualización 2020

Estas opciones ahora están documentadas oficialmente por nodo . Para una máquina de 2GB, probablemente debería usar:

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

Para determinar la cantidad a usar : Puede ver la memoria disponible en una máquina Linux usando free -m. Tenga en cuenta que puede usar la memoria freey la buffers/cachememoria combinadas, ya que buffers/cachese pueden desechar (estos búferes y caché son una buena manera de usar la memoria que de otro modo no se usaría).

Tenga en cuenta la documentación oficial paramax-old-space-size también menciona:

En una máquina con 2 GB de memoria, considere configurarlo en 1536 (1,5 GB)

De ahí el valor anterior. Tenga en cuenta que la cantidad de memoria necesaria para el sistema operativo base no cambia mucho, por lo que podría hacer 3.5 en una máquina de 4GB, etc.

mikemaccana
fuente
1
En el enlace que ha compartido de los documentos de Node.js, dice: "En una máquina con 2 GB de memoria, considere configurar esto en 1536 (1,5 GB)"
Idan Dagan
1
Gracias @IdanDagan, agregaré eso a la respuesta.
mikemaccana
11

Este error ocurre cuando la memoria asignada para la aplicación en ejecución es menor que la memoria requerida. De forma predeterminada, el límite de memoria en Node.js es de 512 MB. Para aumentar esta cantidad, debe establecer el argumento de límite de memoria —-max-old-space-size. Ayudará a evitar un problema de límite de memoria.

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
fuente
y debería tener más memoria RAM asignada
HD ..
Ya no estoy seguro de que esto sea cierto. Ciertamente, en un sistema tengo acceso para ejecutar el nodo 10.20.1, puedo ver (con node --v8-options) que el informe predeterminado es 4096 y, sin configurar max-old-space-sizeel conjunto de pruebas que estoy ejecutando, se asignan hasta 1,5 Gb sin problemas. El artículo mediano vinculado es de 2016, por lo que es probable que las cosas hayan avanzado desde que se escribió.
JaySeeAre
1
Es difícil encontrar una corroboración sobre eso; No puedo encontrar nada explícito en los documentos para V8 o Node. Otro sistema que tengo informa que el valor predeterminado para v10, 12 y 14. es 0. FWIW He encontrado un par de bloggers más recientes que indican la memoria máxima como 1.5Gb ( tejom.github.io/general/nodejs/v8/debugging/2017/ 01/16 /… ) y que la v12 tiene un máximo dinámico según el sistema ( idginsiderpro.com/article/3257673/… ).
JaySeeAre
3
node -e "console.log(`node heap limit = ${require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)"-> v12.18.0 y v14.3.0 -> 2096Mb, v10.20.1 -> 1432Mb
JaySeeAre
@JaySeeAre, gracias por ese comando para mostrar el heap_size_limit. Para un shell UNIX normal, debe citarse de manera diferente:node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'
Sam Watkins
-6

Si solo desea que funcione desde el proyecto en el que está trabajando, siga los dos pasos:

  1. En su proyecto, cd a node_module / @ angular cd node_module / @ angular

  2. Ahora ejecute el siguiente comando exportar NODE_OPTIONS = - max-old-space-size = 8192

satish suryawanshi
fuente
14
¿Por qué tendría que ir al directorio @angular para configurar un entorno var?
mgamsjager