O que é o buffer cache do FreeBSD

Se você abriu o top ou o htop em um servidor FreeBSD e viu quase toda a RAM marcada como "usada", não entre em pânico. O FreeBSD tem um comportamento intencional: ele usa toda a RAM disponível para cache do sistema de arquivos. Isso não e um vazamento de memoria e nem um bug. E design.

O sistema de cache do FreeBSD funciona em duas camadas principais. A primeira e o buffer cache tradicional do kernel, que armazena blocos de disco em memoria para acelerar leituras e escritas. A segunda, quando você usa ZFS como sistema de arquivos, e o ARC (Adaptive Replacement Cache), que pode consumir uma fatia ainda maior da RAM com seu algoritmo de cache mais sofisticado.

A filosofia por trás disso e simples: RAM ociosa e RAM desperdiçada. Cada megabyte que o sistema não esta usando para cache e um megabyte que poderia estar acelerando acesso ao disco. O FreeBSD (e outros sistemas BSD) abraça essa filosofia de forma mais agressiva que o Linux por padrão.

Como funciona

O buffer cache do FreeBSD e gerenciado pelo subsistema de memoria virtual do kernel, controlado principalmente pelo parâmetro kern.maxvnodes e pelo limite de memoria disponível. O kernel aloca páginas de memoria para cache de forma dinâmica, e libera essas páginas quando algum processo precisa de mais memoria real.

O ARC do ZFS vai além: ele implementa um algoritmo de substituição adaptativo que distingue entre páginas "recently used" e "frequently used", tentando manter as mais úteis em memoria. Por padrão, o ARC pode usar até metade da RAM do sistema, mas esse valor e configurável.

A chave para entender e a diferença entre memoria "free", "inactive" e "cached" no output do top. Memoria "inactive" significa que o sistema já usou e pode reconfigurar para outro uso rapidamente. Memoria "cached" e buffer cache do filesystem. Ambas ficam disponíveis imediatamente se um processo precisar. Nenhuma delas esta "presa".

💡
Dica

Para ver um breakdown detalhado da memoria no FreeBSD, use o comando "vmstat -s" ou "top -S". A coluna "Inactive" representa páginas de cache prontas para serem reusadas imediatamente.

Principais causas do consumo

Quando o FreeBSD "come toda a RAM", geralmente uma dessas coisas esta acontecendo:

  • ZFS ARC sem limite configurado: por padrão o ARC cresce até 50% da RAM. Em servidores com muito disco, ele cresce rapidamente ao cachear metadados e dados de arquivos acessados.
  • Workload de banco de dados: PostgreSQL, MySQL e outros bancos de dados fazem muitas leituras de disco. O buffer cache do kernel automaticamente guarda esses blocos em memoria.
  • Varnish ou nginx com arquivos grandes: servidores web que servem arquivos estáticos grandes preenchem o cache do sistema de arquivos rapidamente.
  • Compilações frequentes: compilar código cria e le muitos arquivos temporários. O cache fica cheio com objetos de compilação.

Em todos esses casos, o comportamento e esperado e saudável. O sistema esta fazendo exatamente o que foi projetado para fazer: usar a RAM disponível para acelerar operações.

Como monitorar e diagnosticar

Para entender o que esta consumindo a RAM, use estas ferramentas:

# Memoria geral do sistema
top -S

# Estatísticas detalhadas da VM
vmstat -s | grep -E "pages|cache|free|wire"

# Status do ARC do ZFS
arc_summary

# Tamanho atual do ARC
sysctl kstat.zfs.misc.arcstats.size

# Limite máximo do ARC
sysctl vfs.zfs.arc_max

Para ver quais processos estão usando mais memoria real (não cache):

# Processos por uso de RSS (memoria residente real)
ps aux --sort=-rss | head -20

# Alternativa mais detalhada
top -o rsize
⚠️
Atenção

Não confunda "memoria usada" no top com vazamento de memoria. No FreeBSD, o sistema opera normalmente com quase toda a RAM "em uso" pelo buffer cache. O problema real e quando processos em espaço de usuário (user space) estão crescendo sem controle.

Como configurar limites

Se você genuinamente precisa limitar o quanto o FreeBSD usa para cache (por exemplo, ao rodar máquinas virtuais ou containers que precisam de RAM garantida), existem algumas configurações:

# Limitar o ARC do ZFS a 4GB (em /etc/sysctl.conf)
vfs.zfs.arc_max=4294967296

# Aplicar imediatamente sem reboot
sysctl vfs.zfs.arc_max=4294967296

# Verificar o novo limite
sysctl vfs.zfs.arc_max

Para sistemas sem ZFS (usando UFS), o buffer cache e controlado indiretamente pelo VM subsystem. Você pode ajustar kern.maxvnodes para limitar o número de nos de arquivos cacheados:

# Ver o limite atual de vnodes
sysctl kern.maxvnodes

# Reduzir para liberar memoria (valor padrão e calculado pelo sistema)
sysctl kern.maxvnodes=50000
🚀
Pro tip

Em servidores com bancos de dados que gerenciam o próprio cache (PostgreSQL, MySQL), considere reduzir o ARC do ZFS para dar mais RAM ao buffer pool do banco. O banco de dados geralmente e mais eficiente ao gerenciar seu próprio cache do que o sistema de arquivos.

Comparação com Linux

O Linux tem comportamento similar: ele também usa toda a RAM disponível para cache de páginas (page cache). A diferença e que o Linux usa o parâmetro vm.swappiness e o kswapd para controlar o balanço entre swap e cache, enquanto o FreeBSD usa uma abordagem ligeiramente diferente com seu VM subsystem.

No Linux, você pode ver o uso de cache com "free -h" que mostra explicitamente a coluna "buff/cache". No FreeBSD, a separação e mais granular: "Wired" (kernel), "Active" (em uso), "Inactive" (cache reusavel), "Cache" (buffer cache) e "Free" (disponível imediatamente).

Uma diferença prática: o FreeBSD com ZFS tende a ser mais agressivo no uso de RAM para cache que o Linux com ext4, especialmente em workloads com muita leitura aleatória de arquivos pequenos, onde o ZFS ARC brilha.

Pontos positivos e quando e um problema real

Quando e saudável:

  • RAM "usada" principalmente por buffer cache ou ARC do ZFS
  • Processos em user space com uso de memoria estavelmente baixo
  • O sistema libera cache imediatamente quando processos precisam de memoria
  • Performance de I/O acima do esperado para o hardware

Quando e um problema real:

  • Processo em user space crescendo indefinidamente (vazamento)
  • Sistema usando swap ativamente (indica falta de RAM real)
  • Out of memory (OOM) killer sendo ativado para matar processos
  • Aplicação reclamando de "out of memory" ao tentar alocar

A ferramenta definitiva para diagnosticar vazamentos reais e o procstat ou ktrace, que rastreiam alocações de memoria por processo. Se um processo esta crescendo sem controle, esses comandos mostram exatamente onde.

Casos de uso reais

Servidor de arquivos NAS: FreeBSD com ZFS e um dos stacks mais populares para servidores NAS (como o TrueNAS, que é baseado em FreeBSD). Nesse cenário, o ARC do ZFS consumindo grande parte da RAM e exatamente o que você quer: dados de arquivos acessados frequentemente ficam em memoria, reduzindo latência drasticamente.

Servidor web com conteúdo estático: nginx servindo arquivos de 10-100MB no FreeBSD vai encher o buffer cache rapidamente. O resultado e que requisições subsequentes ao mesmo arquivo saem direto da RAM, sem tocar o disco.

Banco de dados PostgreSQL: PostgreSQL tem seu próprio shared_buffers para cache, mas ainda depende do buffer cache do OS para leituras. No FreeBSD, a combinação do cache do PostgreSQL com o buffer cache do kernel pode ser muito eficiente.

Servidor de build/CI: compilações frequentes do mesmo código-fonte beneficiam enormemente do buffer cache, pois headers e bibliotecas compartilhadas ficam em memoria entre compilações.

Dicas e boas práticas

💡
Dica

Antes de "otimizar" o uso de memoria do FreeBSD, monitore o comportamento real com "vmstat 1" por alguns minutos. Se não houver swap activity e os processos estiverem rodando normalmente, o sistema provavelmente esta operando de forma ótima.

💡
Dica

Para monitorar o ARC do ZFS de forma continua, instale o pacote zfs-stats e use "arc_summary -p" para um resumo detalhado da eficiência do cache (hit rate, miss rate, evictions).

🔴
Cuidado

Não reduza o kern.maxvnodes ou o ARC do ZFS sem antes medir o impacto na performance de I/O. Em workloads com muita leitura de arquivos, reduzir o cache pode aumentar drasticamente a latência e o throughput de operações de disco.

Vale a pena investigar?

Na grande maioria dos casos, o FreeBSD "comendo toda a RAM" e um sinal de que o sistema esta funcionando perfeitamente. O design de usar RAM ociosa para cache e uma das razoes pelas quais o FreeBSD tem excelente performance de I/O em produção.

Antes de abrir um chamado, aumentar RAM ou "otimizar" o sistema, verifique se ha swap sendo usado, se processos em user space estão com RSS crescendo, ou se o OOM killer foi acionado. Se nenhuma dessas coisas estiver acontecendo, o sistema provavelmente esta saudável.

O próximo passo e monitorar com "vmstat 1 10" (10 amostras de 1 segundo) e verificar as colunas "sr" (scan rate) e "pi/po" (page in/out). Se essas colunas estiverem zeradas ou próximas de zero, o sistema não esta sob pressão de memoria real.