O Node.js fica sem memória

245

Hoje eu executei meu script para indexação do sistema de arquivos para atualizar o índice de arquivos RAID e após 4h ele travou com o seguinte erro:

[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

O servidor está equipado com 16 GB de RAM e 24 GB de SSD. Eu duvido que meu script tenha excedido 36 gb de memória. Pelo menos não deveria

O script cria um índice de arquivos armazenados como Array of Objects com metadados de arquivos (datas de modificação, permissões, etc., sem big data)

Aqui está o código de script completo: http://pastebin.com/mjaD76c3

Eu já experimentei problemas estranhos de nós no passado com este script, o que me forçou, por exemplo. divida o índice em vários arquivos, pois o nó estava com falha ao trabalhar em arquivos grandes como o String. Existe alguma maneira de melhorar o gerenciamento de memória do nodejs com enormes conjuntos de dados?

Lapsio
fonte

Respostas:

314

Se bem me lembro, existe um limite padrão estrito para o uso de memória na V8 de cerca de 1,7 GB, se você não aumentar manualmente.

Em um de nossos produtos, seguimos esta solução em nosso script de implantação:

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

Também haveria um novo comando de espaço, mas como eu li aqui: um tour pela coleta de lixo v8, o novo espaço coleta apenas os dados de curto prazo recém-criados e o espaço antigo contém todas as estruturas de dados referenciadas que devem estar em seu caso, a melhor opção.

Felix
fonte
Da mesma forma esta configuração é para nodejs independente sobre o quadro @ Simer.
Felix
Estou desenvolvendo com o angular 4 e obtendo o mesmo problema. Qual deve ser o arquivo yourFile.js para o aplicativo angular?
Vikram
@VikramSingh você está usando ng serveou distribui o resultado da ng buildpasta / dist por outro servidor, como o express? Mas se o seu projeto Angular estiver usando mais do que a memória padrão de 1,7 GB, talvez você tenha um problema de arquitetura em seu aplicativo? Parece que você está usando o env desenvolvimento com NMP começar talvez esta seja uma solução para ele github.com/mgechev/angular-seed/issues/2063
Felix
Eu estou usando construção ng com cli angular e AOT (pasta dist)
Vikram
2
índice, js arquivo @Techdive que você usa para iniciar o servidor
Basit
77

Apenas no caso de alguém encontrar isso em um ambiente em que não pode definir diretamente as propriedades do nó (no meu caso, uma ferramenta de construção):

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

Você pode definir as opções do nó usando uma variável de ambiente se não puder transmiti-las na linha de comandos.

Kamiel Wanrooij
fonte
Você pode explicar o que quer dizer quando diz "... definir as opções do nó usando uma variável de ambiente .."?
Keselme 24/01/19
6
@Keselme Uma variável de ambiente é uma variável que foi definida no servidor a partir da qual todos os processos podem ler os dados. Abra um terminal SSH no seu servidor e digite: MY_VAR = hello e digite: echo $ MY_VAR. Você verá que ele imprime "olá" no terminal. Você acabou de definir uma variável de ambiente e lê-la novamente.
Rob Evans
trabalhou no Ubuntu 18.04, acabou de adicionar o comando de exportação para o meu arquivo bashrc
Rahal Kanishka
76

Se você deseja aumentar o uso de memória do nó globalmente - não apenas um script único, é possível exportar a variável de ambiente, assim:
export NODE_OPTIONS=--max_old_space_size=4096

Então você não precisa jogar com arquivos ao executar builds como npm run build.

Maksim Luzik
fonte
1
Como uma conveniência adicional, adicione ao perfil bash_profile ou zsh.
Tropicalrambler
24

Eu encontrei esse problema ao tentar depurar com o VSCode, então só queria adicionar isso é como você pode adicionar o argumento à sua configuração de depuração.

Você pode adicioná-lo à runtimeArgspropriedade da sua configuração em launch.json.

Veja o exemplo abaixo.

{
"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"
        ]
    }
]}
Astro
fonte
21

Aqui estão alguns valores de sinalizador para adicionar algumas informações adicionais sobre como permitir mais memória quando você inicia o servidor do nó.

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
fonte
pode-se continuar aumentando em potências de 2? deve-se configurá-lo maior que a memória do sistema? caso contrário, o que é uma boa proporção de memória do sistema e tamanho máximo de espaço antigo?
Harry Moreno
3
@HarryMoreno Você pode realmente colocar qualquer valor numérico que desejar. Não precisa estar no poder de 2. No entanto, não tenho certeza da proporção. É apenas um limite máximo, não estará usando toda a memória. Eu defini-lo-ia tão alto quanto você precisa e, em seguida, reduzi-lo, se necessário.
Nicholas Porter
Vou dar uma ram de sistema - 1gb uma tentativa. Supondo que essa vm seja apenas para executar este aplicativo de nó.
Harry Moreno
2
@HarryMoreno Uma boa taxa de memória do sistema para o tamanho máximo de espaço antigo depende inteiramente do que mais está sendo executado em sua máquina. Você pode aumentá-lo em potências de dois - ou pode usar qualquer número. Você pode configurá-lo maior que a memória do sistema - mas encontrará problemas de troca.
Gigimoi 29/07/19
20

eu estava lutando com isso mesmo depois de definir --max-old-space-size.

Então percebi a necessidade de colocar opções --max-old-space-size antes do script de karma.

Também é melhor especificar as duas sintaxes --max-old-space-size e --max_old_space_size meu 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

referência https://github.com/angular/angular-cli/issues/1652

duchuy
fonte
5
" melhor especificar ambas as sintaxes --max-old-space-size e --max_old_space_size " - você não precisa fazer isso, elas são sinônimos. Em nodejs.org/api/cli.html#cli_options : "Todas as opções, incluindo as opções V8, permitem que as palavras sejam separadas por traços (-) ou sublinhados (_)."
ZachB
6
O tamanho máximo de executável foi removido e termina com um erro quando é usado: github.com/nodejs/node/issues/13341
crashbus
Eu tive que cortar --max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_sizee deu
certo
16

Eu tive um problema semelhante ao fazer AOT construção angular. Seguir os comandos me ajudou.

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

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

Chandru
fonte
1
Elogios funcionou para mim, pode ser necessário #:sudo npm -g install increase-memory-limit --unsafe-perm
Leo
11

encontrar e consertar um porco da memória com algo como o memwatch pode ajudar.

NathanQ
fonte
10

Etapas para corrigir esse problema (no Windows) -

  1. Abra o prompt de comando e digite %appdata% press enter
  2. Navegar para %appdata% > pasta npm
  3. Abrir ou Editar ng.cmd no seu editor favorito
  4. Adicione --max_old_space_size=8192ao bloco IF e ELSE

Seu node.cmdarquivo fica assim após a alteração:

@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
fonte
Isso é específico do Windows. O OP não mencionou nada sobre o Windows.
Dan Dascalescu
@DanDascalescu Resposta atualizada. Obrigado por notificar
Umang Patwa
6

A seguinte variável de ambiente pode ser usada:

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

Outra nota: console.log() também consome memória no terminal.

apenas tentei comentar o console.log () no terminal. porque isso também vai levar memória.

Amar Powar
fonte
6
Isso é uma resposta ou comentário para alguma resposta? Há muitas respostas comNODE_OPTIONS= --max-old-space-size=somesize
barbsan
5

se você deseja alterar a memória globalmente para o nó (windows), vá para configurações avançadas do sistema -> variáveis ​​de ambiente -> nova variável do usuário

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

Eu tentei (o código abaixo e está funcionando bem).

  • terminal aberto do diretório raiz do projeto
  • execute o cmd para definir um novo tamanho.

    set NODE_OPTIONS=--max_old_space_size=8172

Ou você pode verificar o link para obter mais informações https://github.com/nodejs/node/issues/10137#issuecomment-487255987

rkumar1904
fonte
4

Eu só quero acrescentar que em alguns sistemas, mesmo aumentando o limite de memória do nó --max-old-space-size, não é suficiente e há um erro do sistema operacional como este:

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

Nesse caso, provavelmente é porque você atingiu o mmap máximo por processo.

Você pode verificar o max_map_count executando

sysctl vm.max_map_count

e aumentá-lo executando

sysctl -w vm.max_map_count=655300

e corrija-o para não ser redefinido após uma reinicialização adicionando esta linha

vm.max_map_count=655300

no /etc/sysctl.conf arquivo

Confira aqui para mais informações.

Um bom método para analisar o erro é executar o processo com strace

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

Eu enfrentei esse mesmo problema recentemente e me deparei com esse segmento, mas meu problema era com o ReactApp. Abaixo, as alterações no comando start do nó resolveram meus problemas.

Sintaxe

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

Exemplo

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

Por que o tamanho é 16000 no tamanho máximo de espaço antigo?

Basicamente, isso varia depende da memória alocada para esse encadeamento e das configurações do nó.

Como verificar e dar o tamanho certo?

Isso é basicamente ficar no nosso motor v8. o código abaixo ajuda a entender o tamanho da pilha do mecanismo do nó 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
fonte
2

Acabei de enfrentar o mesmo problema com minha instância EC2 t2.micro, que possui 1 GB de memória.

Resolvi o problema criando um arquivo de troca usando esse URL e defini a seguinte variável de ambiente.

export NODE_OPTIONS=--max_old_space_size=4096

Finalmente, o problema se foi.

Espero que seja útil para o futuro.

Bat-Orshikh Baavgaikhuu
fonte
1

Para o caso de ajudar as pessoas com esse problema ao usar aplicativos nodejs que produzem logs pesados, um colega resolveu esse problema direcionando as saídas padrão para um arquivo.

Adrien Joly
fonte
1

Se você está tentando iniciar não nodeele próprio, mas algum outro software, por exemplo, webpackvocê pode usar a variável de ambiente e o cross-envpacote:

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

Para empacotamento angular de projeto, adicionei a linha abaixo ao meu arquivo pakage.json na seção scripts .

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

Agora, para agrupar meu código, eu uso em npm run build-prodvez deng build --requiredFlagsHere

espero que isto ajude!

rgantla
fonte
0

Atualize o nó para a versão mais recente. Eu estava no nó 6.6 com esse erro e atualizei para 8.9.4 e o problema desapareceu.

Richard Frank
fonte
0

No meu caso, eu corri npm installna versão anterior do nó, depois de um dia atualizei a versão do nó e ram npm installpara alguns módulos. Depois disso, eu estava recebendo esse erro. Para corrigir esse problema, excluí a pasta node_module de cada projeto e executei npm installnovamente.

Espero que isso possa resolver o problema.

Nota: Isso estava acontecendo na minha máquina local e foi corrigido apenas na máquina local.

Gampesh
fonte
0

Este comando funciona perfeitamente. Como tenho 8 GB de RAM no meu laptop, defino o tamanho = 8192. É tudo sobre ram e você também precisa definir o nome do arquivo. Eu executo o comando npm run build , por isso usei o build.js .

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

No meu caso, atualizei a versão do node.js. para a mais recente e funcionou como um encanto.

Angela Rana
fonte
Olá Angela e bem-vindo ao SO! Talvez você possa especificar a versão exata do Node.js atualizada para futuros leitores? Obrigado!
kant312 12/06
Atualizei para a versão mais recente do LTS: 12.18.0
Angela Rana