Vazamento de Memória em Bot do Discord em Processo de Longa Duração: Correção
🔍 WiseChecker

Vazamento de Memória em Bot do Discord em Processo de Longa Duração: Correção

Se você executa um bot do Discord por horas ou dias, pode notar que o uso de memória aumenta constantemente. Isso é um vazamento de memória, onde o bot não libera a memória que não precisa mais. Com o tempo, pode tornar o bot lento, causar travamentos ou deixá-lo sem resposta. Este artigo explica as principais causas de vazamentos de memória em bots do Discord de longa duração e fornece correções concretas para manter o uso de memória estável.

Principais Conclusões: Corrigindo Vazamento de Memória em Bot do Discord

  • Desative os intents padrão para membros do servidor e presenças: Reduz o uso de memória em 30-50% em bots de longa duração.
  • Adicione client.users.cache.clear() em uma função de limpeza periódica: Impede que o cache de usuários cresça sem limites.
  • Use setInterval para limpar os caches de mensagens e canais a cada 10 minutos: Mantém o uso de memória abaixo de 150 MB mesmo após 24 horas.

Por que Bots do Discord Vazam Memória em Processos de Longa Duração

Discord.js e bibliotecas similares mantêm caches em memória para usuários, mensagens, canais e servidores. Em um bot de longa duração, esses caches crescem à medida que o bot processa eventos. O tamanho padrão do cache é ilimitado. Se o seu bot escuta muitos servidores ou canais, o cache pode inflar para centenas de MBs em poucas horas.

Outra causa são listeners de eventos que não são removidos adequadamente. Quando seu bot se inscreve em eventos como messageCreate ou guildMemberAdd, a biblioteca armazena referências às funções de callback. Se você anexar novos listeners sem remover os antigos, as referências se acumulam e impedem a coleta de lixo.

Uma terceira causa é armazenar objetos grandes em variáveis globais ou coleções. Por exemplo, coletar todas as mensagens de um canal em um array sem limpá-lo fará com que a memória cresça linearmente com o tempo.

Como o Cache Funciona no Discord.js

Discord.js v13 e v14 usam uma classe Collection (que estende Map) para cache. Quando um usuário envia uma mensagem, a biblioteca adiciona o objeto do usuário a client.users.cache se ele ainda não estiver lá. O mesmo acontece para mensagens, canais e servidores. O cache nunca remove entradas a menos que você chame manualmente .delete() ou .clear().

O Papel dos Intents

Os intents controlam quais eventos seu bot recebe. Se você ativar o intent GuildMembers, o Discord envia atualizações da lista de membros para cada servidor. Para um bot em 100 servidores com 500 membros cada, isso significa 50.000 objetos de membro no cache. Desativar intents não utilizados reduz os dados que seu bot precisa armazenar.

Passos para Corrigir um Vazamento de Memória em Bot do Discord

  1. Desative intents desnecessários
    Abra o código do seu bot e localize o construtor Client. Remova GatewayIntentBits.GuildMembers e GatewayIntentBits.GuildPresences a menos que seu bot precise especificamente deles. Esses dois intents causam o maior consumo de memória. Após desativar, reinicie o bot e monitore o uso de memória.
  2. Limite o tamanho do cache de mensagens
    No construtor Client, defina sweepers: { messages: { interval: 600, lifetime: 1800 } } (Discord.js v14). Isso remove mensagens mais antigas que 30 minutos do cache a cada 10 minutos. Para v13, use messageCacheLifetime: 1800 e messageSweepInterval: 600 no objeto de opções.
  3. Limpe o cache de usuários periodicamente
    Adicione uma função que execute a cada 15 minutos usando setInterval. Dentro dela, chame client.users.cache.clear(). Isso remove todos os objetos de usuário em cache. Faça o mesmo para client.channels.cache e client.guilds.cache se o seu bot não precisar mantê-los em memória.
  4. Remova listeners de eventos não utilizados
    Se o seu bot adiciona listeners dinamicamente, armazene a referência e chame client.removeListener(event, callback) quando o listener não for mais necessário. Por exemplo, se você escuta messageCreate em um canal específico, remova o listener quando o bot sair desse canal.
  5. Use WeakRef ou FinalizationRegistry para dados grandes
    Se o seu bot armazena objetos grandes como dados de conexão de voz ou dados personalizados de usuário, use WeakRef para permitir a coleta de lixo quando o objeto não for mais referenciado. Evite armazenar dados em arrays ou maps globais a menos que você os limpe regularmente.
  6. Monitore a memória com process.memoryUsage()
    Adicione um log a cada 10 minutos que imprima process.memoryUsage().heapUsed. Se o valor aumentar mais de 5% por hora, há um vazamento. Use isso para verificar suas correções.

Se o Bot Ainda Tiver Vazamento de Memória Após a Correção Principal

Bot Trava com Erro de Memória Insuficiente

Se o seu bot travar com um erro de falta de memória no heap do JavaScript, aumente o limite de memória do Node.js. Execute o bot com node --max-old-space-size=512 bot.js (512 MB). Isso é uma solução temporária. A correção real é reduzir o tamanho do cache conforme descrito acima.

Memória Cresce Mesmo Após Limpar Caches

Verifique referências circulares. Se o seu código cria objetos que referenciam uns aos outros, eles não podem ser coletados pelo garbage collector. Use a flag --inspect com o Chrome DevTools para tirar snapshots do heap. Procure objetos com um tamanho retido grande que não deveriam estar lá.

Bot Fica Lento com o Tempo

O alto uso de memória força o garbage collector a executar com mais frequência, o que bloqueia o event loop. Se o seu bot responde lentamente após horas de atividade, o vazamento de memória provavelmente é grave. Aplique todas as etapas de correção acima e reinicie o bot.

Gerenciamento de Memória do Bot do Discord: Cache Manual vs Sweeper vs Banco de Dados Externo

Item Limpeza Manual de Cache Sweeper Integrado Banco de Dados Externo (Redis)
Implementação Adicionar setInterval com chamadas .clear() Definir sweepers nas opções do Client Armazenar dados no Redis, consultar sob demanda
Redução de memória Reduz o heap em 50-70% Reduz o heap em 30-50% Memória do bot fica abaixo de 100 MB
Impacto no desempenho Pausa breve durante a limpeza Sem pausa perceptível Latência de rede em cada consulta
Persistência de dados Perdidos na limpeza Perdidos após o intervalo de sweep Persistentes entre reinicializações

Agora você pode identificar e corrigir vazamentos de memória no seu bot do Discord. Comece desativando intents não utilizados e configurando um sweeper. Se o problema persistir, adicione uma limpeza periódica de cache e monitore o uso do heap com process.memoryUsage(). Para bots que precisam ficar online por semanas, considere mover dados persistentes para um banco de dados externo como Redis. Isso reduz o uso de memória do bot para quase zero e evita travamentos.