Quando o servidor congelou: anatomia de um thrashing de memória#
Poucos cenários no desenvolvimento diário são tão frustrantes quanto ver um servidor travar de repente com a CPU em 100% sem uma causa óbvia no código da aplicação.
Recentemente, enfrentei um problema no meu servidor de desenvolvimento Linux: toda vez que eu abria o VS Code Remote (SSH) paralelamente à execução do binário do Antigravity, o consumo de CPU simplesmente estourava, degradando a máquina até quase congelar todo o ambiente.
Neste artigo, compartilho o passo a passo do diagnóstico: como saí da suspeita inicial de contenção de CPU, cheguei à causa raiz na gestão de memória e swap, analisei métricas reais via CLI e apliquei as correções para estabilizar o host.
1. O sintoma inicial e as primeiras hipóteses#
O sintoma era direto: abrir o VS Code Remote + Antigravity resultava em CPU batendo no teto e congelamento geral de sessões SSH.
Inicialmente, quando pensamos em CPU explodindo em ambientes com essas ferramentas, três hipóteses operacionais surgem:
- File Watching e Indexação do VS Code (
inotifyeripgrep): O VS Code Server usa intensamente a APIinotifydo kernel e processosrg(ripgrep) em segundo plano para indexar a árvore de arquivos. Se o workspace tiver muitos arquivos ou diretórios pesados não ignorados (comonode_modulesou.git), ele queima ciclos de processamento sem parar. - Context Switching e Contenção de Threads: Em binários compilados multithreaded (como workers de processamento concorrente), um excesso de trocas de contexto faz as threads passarem mais tempo sendo escalonadas pelo kernel do que executando código útil.
- Garbage Collection Agressivo: Runtimes Node.js (do VS Code Server e da IDE) entrando em loops de GC constantes ao atingir o limite de heap.
Para validar essas ideias, o primeiro passo foi inspecionar o comportamento da máquina via terminal.
2. A falsa saturação de CPU: descobrindo o i/o wait#
Ao abrir o top, o consumo de CPU parecia estar em 98%, mas uma leitura atenta dos campos revelou a verdadeira causa:
%Cpu(s): 4.2 us, 38.5 sy, 0.0 ni, 1.1 id, 55.8 wa, 0.0 hi, 0.4 si, 0.0 st
O tempo de execução em espaço de usuário (us) estava em apenas 4.2%. O que estava consumindo a CPU era:
sy(System / Kernel Time) em 38.5%: O kernel gastando ciclos gerindo tabelas de páginas de memória e filas de interrupção.wa(I/O Wait) em 55.8%: A CPU passando mais da metade do tempo ociosa aguardando operações de leitura e escrita no disco terminarem.
Confirmando com o vmstat 1 5:
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd livre buff cache si so bi bo in cs us sy id wa st
6 4 1845248 182412 24108 412580 1420 2840 3200 4100 4810 9820 5 39 1 55 0
5 5 1845248 179320 24108 411200 1890 3120 4100 4800 5120 11400 4 42 0 54 0
As colunas si (swap-in) e so (swap-out) estavam com milhares de blocos trafegando por segundo. O servidor estava em Memory Thrashing: a memória RAM física esgotou, o kernel começou a despejar páginas ativas para o swap no disco e, a cada tecla digitada ou evento de terminal, o sistema precisava ler do disco e gravar outra página de volta, congelando tudo.
3. Identificando os ofensores de memória#
Para mapear quais processos estavam consumindo memória residente (RSS) e empurrando o host para o swap:
ps -eo pid,ppid,pmem,rss,comm,args --sort=-rss | head -n 12
Os maiores consumidores eram:
node(VS Code Server / Extension Host): Múltiplos workers consumindo mais de 1.8 GB de RSS, varrendo diretórios profundos sem filtros.antigravity-server/ agentes concorrentes: Alocando buffers em memória para context caching.rg(ripgrep): Processos de busca em loop indexando arquivos temporários e logs da IDE.
4. As soluções aplicadas#
A estabilização do host exigiu intervenções em três camadas: configuração do editor, parâmetros do kernel e contenção de recursos via cgroups.
1. Blindando o file watcher do VS code#
Crie ou edite .vscode/settings.json no workspace remoto para ignorar diretórios gigantescos e evitar que o inotify e o rg saturem a memória:
{
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/**": true,
"**/.gemini/**": true,
"**/tmp/**": true,
"**/logs/**": true
},
"search.exclude": {
"**/node_modules": true,
"**/.git": true,
"**/.gemini": true,
"**/tmp": true
},
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 2000
}
2. Otimizando a agressividade de SWAP do kernel#
O Linux vem com vm.swappiness = 60 por padrão. Para servidores de desenvolvimento que rodam editores e agentes em memória, reduza a agressividade do swap e equilibre o cache:
Edite /etc/sysctl.d/99-dev-tuning.conf:
# Reduz o uso precoce de swap no disco
vm.swappiness = 10
# Mantém cache de inodes e arquivos estável na RAM
vm.vfs_cache_pressure = 50
# Ajusta limites para gravação de dirty pages
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
Aplique imediatamente:
sudo sysctl --system
3. Configurando zram com alta prioridade#
Em vez de deixar o thrashing bater em um disco lento, configure uma camada de swap comprimido em RAM (zram) com prioridade mais alta que o swap de disco:
# Alocar 4GB de zram
sudo zramctl --find --size 4G --algorithm lz4
sudo mkswap /dev/zram0
sudo swapon /dev/zram0 -p 100
Como o zram comprime páginas diretamente na memória RAM com latência de microssegundos, páginas ociosas são compactadas sem gerar I/O de disco.
4. Limitando os agentes do antigravity com Cgroups v2#
Para evitar que execuções de subagentes paralelos consumam toda a RAM livre, execute o binário dentro de uma fatia limitada de recursos:
systemd-run --user --slice=agents.slice --property=MemoryMax=3G --property=CPUWeight=50 ./antigravity-server
Considerações práticas de contenção#
Quando seu servidor parecer saturado em 100% de CPU durante sessões de desenvolvimento remoto com agentes de IA, não assuma que a carga é estritamente computacional:
- Inspecione sempre a métrica de
wa(I/O wait) notope as colunassi/sonovmstat. Na grande maioria dos casos, a CPU está simplesmente bloqueada aguardando o disco resolver o thrashing de swap. - Isole workspaces excluindo pastas de dados e históricos dos watchers do VS Code.
- Utilize
zrame fatias dosystemdpara garantir que nem o editor nem os agentes consigam monopolizar o host a ponto de derrubar o SSH.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários