Gestão de memória do Linux: Swap, OOM Killer & Cgroups

12 min de leitura - 31 de maio de 2026

hero section cover
Índice
  • Explicação sobre a gestão de memória no Linux: swap, OOM killer e cgroups
  • Como o Linux gere as páginas de memória
  • Configurar o swap
  • O OOM killer
  • Cgroups e limites de memória
  • Configuração de memória por função do servidor
Partilhar

Como o Linux swap, o OOM killer e o cgroups funcionam em conjunto - com exemplos de configuração para bases de dados, servidores Web e hosts VPS multi-tenant.

Explicação sobre a gestão de memória no Linux: swap, OOM killer e cgroups

O Linux lida com a memória de forma diferente da maioria dos sistemas operativos. Um elevado consumo de RAM nem sempre é um problema — o kernel utiliza ativamente a memória livre para armazenamento em cache, a fim de acelerar as leituras do disco. Mas quando a pressão real sobre a memória aumenta, três mecanismos entram em ação: swap, o OOM killer e os cgroups. Compreender como cada um deles se comporta e como configurá-los é a diferença entre um servidor que se degrada gradualmente sob carga e um que entra em falha sem aviso prévio.

Como o Linux gere as páginas de memória

Cada processo é executado no seu próprio espaço de endereços virtuais, até 128 TB em sistemas de 64 bits. O kernel mapeia estes endereços virtuais para a RAM física através de tabelas de páginas, com o Translation Lookaside Buffer (TLB) a armazenar em cache as pesquisas recentes. Um acerto no TLB demora cerca de 1 nanossegundo; um erro custa 20–100 nanossegundos, o que se acumula em cargas de trabalho que exigem muita memória, como bases de dados.

A memória física é dividida em páginas de 4 KB, e o kernel divide-as em duas categorias:

  • Páginas apoiadas em ficheiros — ligadas a ficheiros no disco. O kernel pode descartar as páginas limpas ou esvaziar as sujas sem necessidade de swap.
  • Páginas anónimas — memória de pilha e heap sem ficheiro de apoio. Estas têm de ser gravadas na área de troca antes de o kernel as poder libertar.

Em servidores com elevada procura de memória, uma grande proporção de páginas anónimas significa que o swap é envolvido precocemente. Observe o si (swap in) e so (swap out) em vmstat 1 — valores persistentes diferentes de zero são o seu primeiro aviso de que o sistema está sob pressão.

Para monitorização, use a ferramenta certa para a tarefa:

FerramentaIdeal paraMétrica-chave
free -hVisão geral rápida de todo o sistemaavailable coluna
vmstat 1Monitorização em tempo real de swap e E/Ssi, so
htopVisualização interativa por processoBarras de memória, lista de processos
smemUtilização precisa por processoUSS (Tamanho do Conjunto Único)
/proc/meminfoDetalhes ao nível do kernelMemAvailable, Dirty, Slab

Um erro comum: observar a free coluna free -h e entrar em pânico. A available coluna é o que importa. Ela inclui a memória que o kernel pode recuperar do cache quando necessário. Um servidor que mostra apenas 512 MB livres, mas 5 GB disponíveis, não está em apuros.

Quando a memória desce abaixo de um limiar, o kswapd demônio do kernel começa a recuperar páginas em segundo plano. Se isso não for suficiente, o kernel passa para a recuperação direta, bloqueando processos até que as páginas sejam libertadas. É daí que vêm os picos de latência. Defina um alerta quando MemAvailable cair abaixo de 10–15% da RAM total para que tenha tempo de reagir.


 

Configurar o swap

O swap é uma área do disco — seja uma partição ou um ficheiro — para onde o kernel move páginas anónimas inativas quando a RAM fica cheia. A diferença de velocidade é significativa: a RAM DDR4 tem uma latência de cerca de 100 ns, enquanto os SSDs NVMe têm cerca de 100 000 ns e os SSDs SATA aproximam-se dos 500 000 ns. O swap é um buffer de segurança, não RAM extra. Um servidor que depende constantemente do swap tem um problema de memória que mais swap não irá resolver.

Utilize um ficheiro de swap em vez de uma partição. É mais fácil de redimensionar e não requer reparticionamento.

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Adicione o ficheiro para /etc/fstab para que persista após reinicializações. A chmod 600 passo é obrigatório — quaisquer dados transferidos da RAM para o swap são legíveis a partir do swap, pelo que o ficheiro não deve ser legível por todos.

Após criar o swap, ajuste vm.swappiness. O valor padrão de 60 é agressivo. Para a maioria das cargas de trabalho de alojamento, é preferível que o kernel dê prioridade à RAM e só utilize o swap como último recurso:

Função do servidorvm.swappinessvm.vfs_cache_pressure
Servidor web geral10–2050
Base de dados (MySQL/PostgreSQL)1–550
Padrão (na maioria das distribuições)60100

Para o dimensionamento da swap: 1–2 GB é suficiente para um VPS de 2 GB que lida com picos de tráfego ocasionais. Em sistemas com 8 GB ou mais, uma swap fixa de 2–4 GB é geralmente suficiente. O objetivo é dar ao kernel uma válvula de escape para páginas inativas, não para ampliar a memória endereçável total.

Em servidores com RAM limitada e CPU ampla, o zram cria uma área de swap comprimida na memória, evitando totalmente a E/S do disco. Vale a pena considerar em hosts VPS multi-tenant onde o NVMe é partilhado entre os tenants. Esteja atento à contenção de E/S se o swap residir no mesmo dispositivo que os ficheiros da base de dados — swap intenso e gravações de disco de alto débito não coexistem bem.

O OOM killer

Quando o kernel esgota a RAM e o swap e não consegue recuperar memória suficiente por outros meios, o OOM killer entra em ação. Ele pontua os processos utilizando a oom_badness() função:

points = (rss_anon + rss_file + rss_shmem + swapents + pgtables_pages) + (oom_score_adj × totalpages / 1000)

O processo com a pontuação mais alta é encerrado. A fórmula favorece os grandes consumidores de memória, e o kernel evita encerrar vários processos em rápida sucessão, verificando se um processo já foi encerrado nos últimos 5 segundos.

Dois tipos de eventos OOM aparecem nos registos:

  • OOM global — todo o sistema está sem RAM e swap. Os registos começam com Out of memory:
  • Cgroup OOM — um contentor ou serviço atingiu o seu memory.max limite. Os registos têm o prefixo Memory cgroup out of memory:

Para rever eventos OOM anteriores:

dmesg -T | grep -i "out of memory"
journalctl -k --grep="oom"

Preste atenção ao order campo nos registos OOM. Um valor acima de 0 sugere fragmentação de memória em vez de esgotamento total — o kernel não conseguiu encontrar páginas contíguas suficientes, mesmo com memória livre disponível.

Pode influenciar quais os processos que o OOM killer alveja ajustando /proc/<pid>/oom_score_adj. O intervalo vai de -1000 (nunca encerrar) a +1000 (encerrar primeiro). Para serviços geridos pelo systemd, defina isto permanentemente no ficheiro de unidade:

[Service]
OOMScoreAdjust=-1000

Parâmetros sysctl adicionais para ajustar o comportamento do OOM:

ParâmetroValorEfeito
vm.overcommit_memory0Modo heurístico de overcommit padrão
vm.overcommit_memory2Modo estrito; impede alocações que excedam RAM × overcommit_ratio + swap
vm.panic_on_oom1Reinicia em vez de encerrar um processo
vm.oom_kill_allocating_task1Encerra o processo que desencadeou o OOM em vez do maior consumidor

Para monitorização proativa, verifique /proc/pressure/memory (Informações de Estagnação de Pressão, disponível desde o kernel 4.20). Observe o some avg10 valor: abaixo de 5% é normal; se se mantiver acima de 20%, significa que é provável que ocorra um evento OOM. Um allocstall contador em /proc/vmstat é outro sinal precoce — ele conta os bloqueios de recuperação direta, que muitas vezes precedem as interrupções por OOM. Ferramentas como systemd-oomd ou earlyoom podem agir com base nos limiares do PSI antes de o OOM killer do kernel ser acionado.

Cgroups e limites de memória

Os grupos de controlo (cgroups) permitem organizar processos em grupos e impor limites rígidos de recursos. Introduzidos no Linux 2.6.24, são a base dos ambientes de execução de contentores, incluindo Docker, Podman, Kubernetes e LXC. O kernel monitoriza a utilização de memória por cgroup, abrangendo memória anónima, páginas suportadas por ficheiros e objetos do kernel. Se um cgroup atingir o seu limite, o kernel recupera memória dentro desse grupo ou aciona um OOM kill no âmbito do cgroup.

O Cgroup v1 e o v2 diferem principalmente na forma como estão estruturados. O v1 monta cada controlador (memória, CPU, E/S) separadamente sob /sys/fs/cgroup/<controller>/, o que leva a um acompanhamento inconsistente dos recursos. A v2 utiliza uma hierarquia unificada em /sys/fs/cgroup/. O Kubernetes mudou para a v2 como padrão na versão 1.25 e deixou de suportar a v1 na 1.31.

Para verificar qual a versão que o seu sistema utiliza:

stat -fc %T /sys/fs/cgroup/

cgroup2fs significa v2; tmpfs normalmente significa v1.

RecursoCgroup v1Cgroup v2
HierarquiaMúltipla, por controladorÚnica, unificada
Limite rígido de memóriamemory.limit_in_bytesmemory.max
Limite de memória flexívelmemory.soft_limit_in_bytesmemory.high (limitações)
Acompanhamento da utilizaçãomemory.usage_in_bytesmemory.current
Métricas de pressãoLimitadoPSI integrado

Os principais controlos de memória no cgroup v2:

ParâmetroTipoDescrição
memory.maxLimite rígidoExceder este valor aciona o OOM killer
memory.highLimite flexívelLimita a alocação e aciona a recuperação antes de atingir o limite rígido
memory.lowProteção flexívelA memória abaixo deste limiar é recuperada em último lugar
memory.minProteção rígidaA memória abaixo deste nível nunca é recuperada
memory.swap.maxLimite de swapDefina como 0 para desativar a troca para este cgroup
memory.oom.groupBooleanoSe ativado, o OOM encerra todos os processos no cgroup em conjunto

Uma regra prática: defina memory.high cerca de 10–20% abaixo memory.max para dar ao kernel espaço para recuperar antes de atingir o limite rígido. Ao dimensionar memory.max, acrescente 20–30% acima do pico de utilização da aplicação para ter em conta a cache de páginas, que conta para o total de memória do cgroup.

Gerencie cgroups via systemd em vez de gravar diretamente no sistema de arquivos do cgroup. Use diretivas de arquivo de unidade como MemoryMax=, MemoryHigh=, e MemoryMin= para limites persistentes. Para testes rápidos:

systemd-run --scope -p MemoryMax=512M <command>

Para pools de trabalhadores de servidores web, definir memory.oom.group=1 garante um encerramento limpo se um trabalhador exceder o seu limite — sem processos órfãos deixados para trás. Para motores de base de dados, memory.min protege o conjunto de buffers de ser recuperado sob pressão a nível do sistema.

Configuração de memória por função do servidor

As definições de memória corretas dependem da função do servidor. Aplicar a mesma configuração a uma base de dados e a um servidor web PHP prejudicará um deles.

Função do servidorvm.swappinessEstratégia OOMPolítica de Cgroup
Base de dados1–5Proteger (OOMScoreAdjust=-900)Utilizar memory.min para proteger o buffer pool
Servidor Web/aplicações10–20PadrãoLimite por pool de trabalhadores via memory.max
Trabalhador em segundo plano60Eliminável (OOMScoreAdjust=+200)Limitação via memory.high
VPS multi-tenant60 (com zram)PadrãoIsolamento rígido por inquilino via memory.max

Para MySQL e PostgreSQL, aloque 50–70% da RAM disponível para innodb_buffer_pool_size, desative as Transparent Huge Pages para reduzir picos de latência e proteja o processo com OOMScoreAdjust=-900 no ficheiro de unidade do systemd.

Para o PHP-FPM, dimensione os conjuntos de trabalhadores de acordo com a utilização real de memória. Cada trabalhador utiliza normalmente 30–100 MB. Divida a RAM alocada pelo tamanho médio dos trabalhadores para obter um pm.max_children . Use memory.max nos cgroups para limitar o pool.

Para cargas de trabalho com grande volume de gravações, defina vm.dirty_ratio para cerca de 10% e vm.dirty_background_ratio para 3%. Isto limpa as páginas sujas com maior frequência, evitando grandes bloqueios de E/S.

Torne o ajuste do kernel persistente guardando os parâmetros em /etc/sysctl.d/90-memory.conf. As configurações aplicadas em tempo de execução são perdidas ao reiniciar o sistema.

Para um resumo dos valores recomendados por função:

ParâmetroServidor Web/aplicaçõesServidor de base de dados
vm.swappiness10–201–5
vm.vfs_cache_pressure5050
vm.dirty_ratio15%10%
vm.min_free_kbytes6553665536
Proteção OOMPadrãoOOMScoreAdjust=-1000

Se estiver a executar cargas de trabalho de alta densidade e precisar de um servidor com capacidade suficiente para aplicar estas políticas corretamente, vale a pena dar uma vista de olhos aos servidores dedicados da FDC.

Blogue

Em destaque esta semana

Mais artigos
Gestão de memória do Linux: Swap, OOM Killer & Cgroups

Gestão de memória do Linux: Swap, OOM Killer & Cgroups

Como o Linux swap, o OOM killer e o cgroups funcionam em conjunto - com exemplos de configuração para bases de dados, servidores Web e hosts VPS multi-tenant.

12 min de leitura - 31 de maio de 2026

Guia de configuração do Prometheus e do node_exporter

15 min de leitura - 29 de maio de 2026

Mais artigos