VM lenta? Auditando CPU, RAM e um .bashrc que corrompe sozinho

Como auditei uma VM Oracle Cloud que travava e encontrei um .bashrc corrompido enchendo a memória — diagnóstico por evidência, não por palpite.

O problema

Minha VM (sigla para Virtual Machine, ou Máquina Virtual — que é basicamente um computador que alugamos na nuvem) na Oracle Cloud, no plano gratuito e com processador ARM, começou a apresentar um comportamento estranho: do nada, ficava extremamente lenta.

Para você ter uma ideia, a conexão via SSH (o método seguro que usamos para acessar o terminal desse servidor remoto) demorava muito para responder, os comandos travavam no terminal e até o assistente claude levava cerca de 30 segundos de atraso antes de dar qualquer sinal de vida.

Reiniciar o servidor até resolvia, mas era algo temporário. Eu me pegava pensando: será que a máquina virtual é muito fraca? O problema é o processo do LiteLLM (a ferramenta que gerencia as chamadas de IA)? É a minha rede de internet? Ou a VPN do Tailscale?

O grande desafio de dizer que “está lento” é que isso é apenas um sintoma, e não nos diz a causa raiz. É como estar com febre: você sabe que algo está errado, mas precisa de exames para descobrir o que é. Você precisa medir para entender.

Nessa auditoria, descobri duas coisas: a CPU (o “cérebro” do computador) não era o gargalo (o que foi uma surpresa), e sim o arquivo .bashrc (o arquivo de configurações que roda automaticamente toda vez que fazemos login), que tinha um loop infinito consumindo a memória RAM aos poucos a cada novo acesso.

Este artigo é o passo a passo de como cheguei a esse diagnóstico, na ordem exata em que investiguei — porque no mundo de TI, a ordem dos testes importa muito para você não se perder.

Passo 1: o que está consumindo, agora

Antes de chutar qualquer palpite, é preciso medir. O comando mais direto e honesto para diagnosticar o uso do sistema no Linux é o seguinte:

top -b -n 1 | head -20

Se você tiver instalado, pode usar também o htop, que é uma versão visualmente mais fácil de ler (pense neles como o “Gerenciador de Tarefas” do Windows, mas no terminal).

O que eu estava procurando ali era simples: qual programa (ou processo) estava no topo da lista usando mais CPU (capacidade de processamento) e memória RAM (o espaço de trabalho temporário do sistema).

Na minha máquina virtual, veio a primeira surpresa: o node (que roda o Claude Code) e o litellm estavam consumindo recursos normalmente. Porém, havia um processo chamado bash (o próprio programa do terminal Linux) consumindo 18% da memória RAM. Isso é extremamente estranho para um shell (janela de comandos) que não deveria estar executando nada no momento.

Para investigar melhor a memória, usei:

ps aux --sort=-%mem | head -10

Ao ordenar a lista pelo uso de memória, vi com clareza: dois processos bash ocupavam um espaço desproporcional. Um deles era o terminal que eu estava usando no momento pelo SSH. O outro era um processo “órfão” — ou seja, um programa que ficou esquecido e rodando em segundo plano de um login antigo que eu já tinha fechado.

Passo 2: a origem do bash gordo

Um programa bash gastar muita memória sem você estar digitando ou executando nada é um sinal claro de que ele está preso rodando alguma tarefa em loop (repetição contínua). Para entender o que era, chequei o horário em que o processo tinha começado a rodar:

ps -o pid,lstart,cmd -p <PID>

Descobri que o processo estava ativo há dias. E o comando (cmd) indicava bash -l (que significa um login shell, ou seja, a sessão inicial que abre quando nos conectamos). Uma sessão de dias atrás já deveria ter sido encerrada.

Foi aí que me veio a sacada principal do diagnóstico: toda vez que um login shell é iniciado, ele carrega o arquivo ~/.bashrc.

O .bashrc funciona como uma lista de instruções de “boas-vindas” que o Linux executa a cada entrada. Se esse arquivo tiver uma função escrita de forma errada que chama a si mesma sem parar (o que chamamos na programação de recursão), cada novo login vai iniciar um ciclo de processamento que consome memória sem parar. Fui conferir o arquivo.

Passo 3: o .bashrc que corrompe sozinho

Abri o arquivo ~/.bashrc e examinei as funções personalizadas. Encontrei uma função que eu tinha adicionado rápido demais, que estava assim:

empurrar() {
  empurrar "$1"
}

Repare no problema: a função empurrar chama a própria função empurrar. É uma recursão infinita, como colocar dois espelhos um de frente para o outro, sem uma condição para parar.

Toda vez que o sistema carregava o .bashrc no login e essa função era acionada (ou chamada por outro atalho/alias), a memória RAM começava a ser consumida sem parar. Era um consumo lento o suficiente para a máquina virtual aguentar várias horas antes de travar, mas constante o bastante para, de tempos em tempos, derrubar o desempenho de tudo.

Corrigi o problema removendo essa chamada infinita (a função original deveria apenas enviar chaves SSH, e não chamar a si mesma). Em seguida, encerrei os processos antigos que ainda estavam rodando soltos na memória:

# Matou os shells órfãos
pkill -u $USER -o bash

Assim que fiz isso, a memória RAM da máquina virtual voltou ao nível normal e a lentidão que parecia “aleatória” sumiu por completo.

Passo 4: separar CPU de rede

A CPU não era a vilã do problema. No entanto, a máquina virtual ainda parecia meio travada ao conectar pelo SSH.

É aqui que entra um conceito fundamental de tecnologia: lentidão percebida nem sempre é falta de CPU ou RAM — também pode ser latência de rede. Latência é o tempo que a informação leva para ir do seu computador até o servidor e voltar (o “tempo de resposta”).

Para tirar a prova, fiz dois testes de rede:

# Latência até o gateway Tailscale
ping -c 5 100.x.x.x

# Throughput pra um host conhecido
curl -o /dev/null -w "%{time_total}\n" https://cloudflare.com/cdn-cgi/trace

O teste de ping (tempo de resposta) deu normal. O teste de curl (velocidade de download/transferência) foi rápido. Conclusão: a minha conexão de rede estava perfeita.

Se a rede estava boa, a lentidão no SSH significava que o próprio terminal estava demorando para responder — o que confirmava que o arquivo .bashrc (carregado logo no login do SSH) estava executando tarefas desnecessárias.

Nessa busca, encontrei também o comando neofetch (aquela ferramenta visual que desenha o logo do sistema em arte ASCII e mostra dados do computador) sendo chamado a cada login. Em uma máquina virtual ARM com processamento modesto, o neofetch adicionava de 1 a 2 segundos de atraso a cada conexão SSH. Um pequeno detalhe, mas que tornava o uso chato e lento.

A auditoria como procedimento fixo

Depois dessa experiência, criei um roteiro fixo de auditoria para executar sempre que a máquina virtual parecer lenta. Eu sigo sempre a mesma ordem e os mesmos comandos:

# 1. O que está consumindo agora (CPU e memória)
ps aux --sort=-%mem | head -10
ps aux --sort=-%cpu | head -10

# 2. Disco cheio? (causa misteriosa de lentidão)
df -h /

# 3. Tem processo órfão?
ps -o pid,lstart,cmd -u $USER | grep -v '?'

# 4. Rede
ping -c 3 <host-exemplo>

São apenas quatro comandos que levam trinta segundos. Em 80% dos problemas, um deles vai mostrar exatamente a causa. O objetivo aqui não é decorar linhas de código, mas sim ter um método de investigação para não ter que adivinhar a solução do zero toda vez.

O que aprendi

A maior lição que fica para qualquer situação em TI é: “está lento” é apenas um sintoma, nunca o diagnóstico definitivo.

Toda vez que eu achava que o problema era “a máquina virtual que é fraca”, eu estava apenas dando um palpite — e o palpite me impedia de analisar dados reais. Investigar com base em evidências (conferir CPU, RAM, espaço em disco, rede e processos esquecidos) pode parecer mais demorado no primeiro minuto, mas economiza muito tempo no final, pois te leva direto à solução em vez de te fazer reiniciar a máquina às cegas.

E o segundo aprendizado técnico: qualquer código ou função que você coloca no seu ~/.bashrc se torna parte da inicialização do seu ambiente de trabalho.

Se você errar um código em um script qualquer, você recebe uma mensagem de erro clara ao executá-lo. Mas se você errar algo no .bashrc, você cria uma lentidão invisível que dificilmente vai associar à causa original. Por isso, trate o .bashrc com cuidado de ambiente de produção: teste muito antes de salvar, use técnicas seguras para inserir textos (como o heredoc) e nunca crie funções que chamam a si mesmas sem um ponto de parada.

Leia também

Comentários

Carregando comentários…

Deixe um comentário