Melhorando o gerenciamento de memória do Linux
De modo geral, o Linux tem um excelente gerenciamento de memória, e isso vai muito além de simplesmente manter dados na RAM e depois escrever ou ler do disco. Existe toda uma engrenagem por trás disso, envolvendo tanto o kernel quanto componentes do próprio processador, como a MMU (Memory Management Unit) e a TLB (Translation Lookaside Buffer), que trabalham juntos para usar a memória da forma mais eficiente possível.
A memória RAM é dividida em pequenos blocos chamados páginas, normalmente de 4 KB cada (algo parecido com aqueles quadradinhos do antigo defrag do Windows). Essas páginas têm endereços físicos (reais), mas os programas não acessam esses endereços diretamente. Eles só “enxergam” endereços virtuais.
É aí que entra o esquema de memória virtual: cada processo tem seu próprio mapa de endereços virtuais, que é traduzido para endereços físicos pela MMU. Isso garante isolamento entre processos e permite que vários programas achem que estão usando muita memória, mesmo quando a RAM física é limitada. Não é que 4 GB “virem” 32 GB de verdade, mas o sistema consegue usar melhor a memória disponível, reciclar páginas e até jogar dados pouco usados para o disco (swap), mantendo tudo funcional.
Essa tradução de endereços acontece o tempo todo, e para não ficar lento demais existe a TLB, que é basicamente um cache ultra-rápido dentro do processador. Ela guarda traduções recentes de endereços virtuais → físicos, evitando que o sistema tenha que consultar as tabelas de páginas na RAM a cada acesso.
Funciona mais ou menos assim (bem por cima):
-
Um programa pede acesso a um dado.
-
A CPU consulta a TLB primeiro.
-
Se a tradução estiver lá (TLB hit), acesso imediato.
-
Se não estiver (TLB miss), o sistema vai consultar as tabelas de páginas na RAM.
-
Achando a tradução, a TLB é atualizada e o programa segue normalmente.
-
Se a página não estiver na RAM, acontece um page fault.
- Se a página existir no disco (cache de arquivos ou swap), ela é carregada para a RAM.
- Se não existir em lugar nenhum, o processo recebe erro e normalmente é encerrado (segfault).
-
Kernel panic por corrupção de memória é raro e geralmente indica bug sério de driver, hardware defeituoso ou erro grave no kernel — não é algo comum em page fault normal.
Depois desse rolo todo, entra o THP. THP significa Transparent Huge Pages (Páginas Gigantes Transparentes). O sistema de memória gosta de dados contíguos, porque isso reduz o número de traduções e acessos à TLB, melhorando desempenho.
O problema é que, com o tempo, a RAM vai ficando fragmentada. Em máquinas com bastante memória (16 GB ou mais) isso costuma ser menos problemático, porque ainda sobra espaço para achar áreas grandes contíguas. Já em máquinas mais modestas, isso fica mais complicado.
O THP tenta resolver isso usando páginas maiores, normalmente de 2 MB, no lugar das páginas padrão de 4 KB. Com páginas maiores:
-
Menos entradas na TLB;
-
Menos page faults;
-
Melhor desempenho em cargas pesadas (bancos de dados, VMs, renderização, etc.).
Essa união é transparente porque:
-
O programa não sabe que está usando páginas grandes;
-
O programador não precisa mudar nada no código;
-
Quem decide tudo é o kernel + MMU.
Agora vem a parte delicada. Em máquinas mais fracas ou com pouca RAM, pode entrar em ação o khugepaged, que é um daemon do kernel responsável por tentar agrupar páginas pequenas em huge pages. Ele não “desfragmenta” a memória exatamente como um defrag de disco, mas faz compactação de memória, movendo páginas na RAM para criar blocos contíguos grandes o suficiente.
Isso tem custo:
- Usa CPU;
- Move dados na RAM;
- Pode gerar picos de latência.
Por isso, dependendo do cenário (hardware antigo, desktop leve, uso interativo), o THP pode mais atrapalhar do que ajudar. Já em servidores e workloads pesados (máquinas virtualizadas, jogos cabeludos e aplicações que demandam muita RAM), costuma ser vantajoso.
No fim das contas:
- Para os programas, dados são dados;
- Tudo é virtualizado;
- O “Transparent” vem daí;
- O “Huge” vem do tamanho maior das páginas (2 MB em vez de 4 KB).
De um modo geral as máquinas mais medianas (como i3 de 6ª geração pra cima) o recurso de THP é bem mais eficiente devido à capacidade do processador em lidar com o gerenciamento de memória (cache maior, maior velocidade, RAM já DDR4), vamos ver então esse impacto em máquinas pererecas.
A imagem acima mostra a resposta do THP em uma máquina perereca com processador C2D E7400 e 2GB de RAM DDR3.
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
O primeiro deverá mostrar algo como:
always [madvise] never
O segundo deverá mostrar algo como:
always defer [defer+madvise] madvise never
- Always = THP sempre ativo mesmo que não precise;
- Madvise = só ativa o THP quando necessário;
- Never = sempre desligado.
A ativação ou não depende do tipo de máquina, conforme a tabela abaixo:
Se estiver madvise está tudo ok, é a melhor opção mas dentro do que mostra a imagem acima. A quantidade de RAM também influencia, então como base máquinas pererecas com 4GB de RAM pra baixo pode-se usar o modo NEVER; já pra setups mais robustos, o MADVISE é o mais indicado. Vamos então criar um serviço para fixar o modo caso seja necessário. Abra o Terminal e digite:
sudo nano /etc/systemd/system/enable-madvise-thp.service
Cole dentro o seguinte:
[Unit]
Description=Set Transparent Huge Pages to madvise
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c ' \
echo madvise > /sys/kernel/mm/transparent_hugepage/enabled; \
echo defer+madvise > /sys/kernel/mm/transparent_hugepage/defrag; \
'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Salve o arquivo (CTRL + O) e feche-o (CTRL + X). Ainda no Terminal:
sudo systemctl daemon-reexec
sudo systemctl enable --now enable-madvise-thp.service
Reinicie a máquina. Rode os comandos abaixo e veja se o modo Madvise está entre colchetes:
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
Seu sistema está "madviseado". Se precisar mesmo desabilitá-lo por conta de ser máquina muito perereca, no Terminal:
sudo nano /etc/systemd/system/disable-thp.service
Coloque dentro:
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=basic.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
ExecStart=/bin/sh -c 'echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Salve o arquivo e digite os comandos abaixo, reiniciando a máquina logo depois:
sudo systemctl daemon-reexec
sudo systemctl enable --now disable-thp.service
De volta ao Terminal, digite:
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
Deverá aparecer NONE entre colchetes. Atenção que esse tweak não vai funcionar em todas as máquinas: máquinas pererecas com pouca RAM (4GB) e processador perereca (dualcore sem HT, série de primeira e até segunda geração Intel, Atom, Celeron e outros), placas-mãe 775, RAM DDR2 ou mesmo DDR3 são as mais propensas a sofrerem com THP ativo pois a combinação desses fatores influenciam no desempenho da máquina. A minha máquina é:
- Intel Dual Core C2D E7400 2.8Ghz;
- 4GB de RAM DDR3;
- Placa-mãe Asrock G41-VS3 (soquete 775, sem AHCI na porta Sata, tudo onboard;
- Disco rígido de 500GB
e, dentro do que eu faço, tudo funciona sem problemas no modo Madvise ativado. E repetindo, máquinas mais robustas com mais de 8GB não precisam desse tweak mas é bem válido usar o modo Madvise pois o THP só vai ser acionado se e quando for preciso.




Nenhum comentário:
Postar um comentário