Como funciona o gerenciamento de memória no Linux

  1. N0625
    Fala, galera!!

    Vou mostrar neste artigo como funciona o gerenciamento de memória no Linux, inclusive com dicas para administrar a memória SWAP. ^^

    O Linux tem uma forma bastante interessante de gerenciar a memória. O sistema de fato não necessita de muita memória para sua operação e conforme os programas vão sendo abertos, mais memória vai sendo alocada de forma mais eficiente. O sistema lida bem em casos de sobras de memória, utilizando os MBytes livres dos módulos como cache de disco. Cache de disco são porções da memória RAM usadas por arquivos e bibliotecas lidos do HD que têm uma maior probabilidade de serem acessados, uma espécie de Prefetch, o que melhora o desempenho do sistema. É fácil comprovar a eficiência o cache de disco: abra um programa como o Firefox ou o OpenOffice; o primeiro carregamento é demorado, certo? Agora feche o programa e abra-o novamente: levou muito menos tempo, né? Esse recurso está presente também no Windows e no Vista ele foi melhorado. Por isso não se assuste se no Ksysguard do KDE você verificar que sua memória RAM estiver quase que totalmente ocupada, mesmo com poucos programas abertos: é o cache de disco que está em ação usando parte da memória livre que você dispõe.

    Além do Ksysguard, temos o Monitor do sistema no Gnome como programas gráficos de monitoramento dos recursos do sistema. Via terminal temos o top e o free. O top detalha os processos em execução além de outras informações como o estado dos processos, memória consumida por cada um, uptime do sistema e recursos de memória. O free (o parâmetro -m exibe as informações em MBytes) exibe informações precisas sobre o uso dos recursos de memória do sistema. Vamos ver ele na prática, no meu caso tenho 2,25GB de RAM física, 2 GB de espaço em disco para a partição SWAP e poucos programas abertos. A distribuição usada é o Debian Etch Kernel 2.6.18-4.

    [​IMG]

    No momento que foi tirada esta SS, 591MB de memória física estavam sendo utilizados, mas na verdade eu não tinha 591MB utilizados pelos programas abertos e pelo sistema em geral. 347 MB estavam sendo cacheados, ou seja, sendo usados para cache de disco (cached) e 51MB estavam sendo usado para buffers de memória. Fazendo as contas, descontando os buffers e cache do sistema, a memória utilizada para o uso e manutenção do funcionamento do sistema no momento era de 193 MB:

    591 (memória física utilizada) - 398 (buffers + cache) = 193 MB

    Se eu abrir o Monitor do sistema do Gnome (um front-end para o comando top), serão reportados 193MB em uso pelo sistema.

    [​IMG]

    Ao contrário do Ksysguard, o Monitor do sistema do Gnome reporta a memória em uso, não incluindo a memória utilizada como cache de disco.

    Conforme mais memória é requisitada, o sistema passa a abrir mão do cache de disco e passa a mover arquivos e bibliotecas não usadas há algum tempo da memória RAM para a memória virtual ou swap, liberando memória física para os aplicativos. Há um pequeno impasse no uso de memória SWAP no Linux. O Swap é visto com maus olhos por causa do Windows 98, que gerencia a memória virtual de forma totalmente errádica. No 98, mesmo com memória física sobrando o sistema teima em fazer swap, que é feito no arquivo Win386.swp, prejudicando o desempenho, já que a leitura dos dados da memória SWAP (que é feita em um arquivo no HD no caso do Windows) é mais morosa do que a leitura na memória RAM. Era possível corrigir essa deficiência com a instrução "ConservativeSwapfileUsage=1" no System.ini, mas mesmo assim o Windows 98 (e Me) é péssimo para gerenciar a memória. Na família NT o gerenciamento de memória é mais eficiente e o uso do arquivo de SWAP é mais racional, aliás no Windows NT4/2000/XP/2003/Vista e 2008 o arquivo de paginação (pagefile.sys) é utilizado também para uso interno do sistema, como as informações de despejo de memória.

    O Linux possui algoritmos refinados que administram o uso de memória SWAP somente quando necessário, especialmente no Kernel 2.6. Numa máquina com 512MB ou mais o uso de SWAP não é requisitado o tempo todo, o que não acontece numa máquina com 256 MB. Mesmo assim em algumas distros fazem o uso do SWAP em máquinas com fartura de memória, mesmo que em pequena quantidade. No caso dos dados movidos para o SWAP sejam de repente requisitados, haverá uma pequena demora na leitura, pois como já dito, a leitura no HD é mais demorada do que o acesso na memória física.

    Vou transcrever aqui um trecho de um dos livros do Carlos E. Morimoto que ensina como administrar o uso do SWAP apenas quando necessário.

    "...

    Ainda assim (ao usar uma distribuição com o Kernel 2.6), você pode configurar o comportamento do sistema em relação à memória SWAP através de um parâmetro do Kernel, definindo através do arquivo "/proc/sys/vm/swappiness". Este arquivo contém um número de 0 a 100, que determina a predisposição do sistema a usar swap. Um número baixo faz com que ele deixe para usar swap apenas em situações extremas (configuração adequada a micros com muita RAM), enquanto um número mais alto faz com que ele use mais swap, o que mantém mais memória RAM livre para uso do cache de disco, melhorando o desempenho em micros com pouca memória.

    Se você tem um micro com 1 GB de RAM e quer que o sistema quase nunca use swap, use:

    # echo "20" > /proc/sys/vm/swappiness

    Em micros com 256 MB ou menos, aumentar o uso de swap mantém mais memória disponível para abrir novos aplicativos e fazer cache de disco. O programa que está sendo usado no momento e novos programas abertos ficam mais rápidos mas, em troca, programas minimizados a muito tempo são movidos para a swap e demoram mais para responder quando reativados. Para aumentar o uso de swap, use:

    # echo "80" > /proc/sys/vm/swappiness

    Para tornar a alteração definitiva, adicione o comando em algum arquivo de inicialização do sistema, como o "/etc/rc.d/rc.local" ou "/etc/init.d/bootmisc.sh".

    ..."
    Linux Ferramentas Técnicas 2ª Edição - pág 112.

    Pessoalmente, recomendo o uso de uma partição SWAP, mesmo que seja de 512MB para uso em casos de falta de memória, principalmente para as máquinas usadas em aplicações pesadas como edição de áudio, vídeo e imagem. Claro que em situações de fartura, digamos a partir de 1GB, a partição de SWAP pode ter uns 256 a 512MB reservados. Nos casos de máquinas que possuam menos de 512MB, recomendo o uso de SWAP com tamanho a partir de 1GB para que o sistema tenha para onde correr no caso de falta de memória física, já que na falta de memória RAM para os aplicativos e a ausência de uma partição SWAP, o sistema não terá para onde recorrer e os programas começarão a serem fechados por falta de memória; na pior das hipóteses o travamento do sistema nestas condições é inevitável.

    Caso você tenha se arrependido em não ter criado uma partição SWAP e agora se vê numa situação delicada, é possível criar um arquivo de SWAP na raiz do sistema. Digamos que você queira 512MB de memória SWAP, abra um terminal como root e digite:

    # dd if=/dev/zero of=/swap bs=1024 count=524288
    # mkswap /swap
    # swapon /swap

    O valor de "count" não precisa ser exato (524288 equivalem a 512MB), poderia ser o valor 500000 (500000 = ~488MB). Esta é uma solução temporária e menos eficiente, já que estamos criando um arquivo de swap que funciona de forma semelhante ao que é encontrado no Windows, embora de forma mais eficiente. Uma partição SWAP já é organizada especificamente para a tarefa de memória virtual.

    See ya! ;)
  2. dcardosoa
    Parabens! Muito interessante!
  3. Chino Ventura
    Reporta pros modera, eles poderiam deixar teu tópico como fixo.. digo pq não sei se já há algum com o mesmo tema.. valeu!
  4. Marcelo de Matos Soeiro
    Muito bom o tópico, mesmo... e, lembrar do 'conservativeswapfileusage=1' até me causa náuseas... ;)
    Uma pergunta que nunca encontrei resposta: e se eu desativar o swap, mesmo com muita memória como você, 2GB... o que acontece quando ela se enche?!?! O excedente é simplesmente descartado (o que parece óbvio) ou o sistema diz que não tem mais memória e aborta?!?!
    Fiquem com Deus.
  5. cleuby
    Muito legal, bacana mesmo, muitas pessoas irão se benificiar deste post.
  6. zerocow
    outra coisa...

    como eu posso almenter as prioridades dos programas?

    pois mesmo polindo o kernel, mudando o timeslice, e a preempção...
  7. N0625
    Valeu, galera!! É um assunto que eu gosto muito de ler e entender como funciona: os detalhes técnicos dos sistemas operacionais.

    Bem, em teoria eu acho também que o sistema descarta o excedente, abrindo mão cada vez mais frequente do cache e realoca memória para as necessidades, o que de fato é bem ágil no Linux. No Windows quando um programa pesado é encerrado, a desalocação da memória usada é imediata só que por algum motivo parte dessa memória usada é despejada no pagefile.sys (quem usa Windows deve ter percebido esse comportamento, basta observar o indicador de leitura do disco rígido após fechar o programa), sendo "esvaziado" gradativamente. Sinceramente não entendo o porque desse comportamento, mas é por esse motivo que não aconselham desativar a memória virtual no Windows, mesmo se o PC tiver 64TB (!!!) de RAM, aliás muitos programas for Windows (sobretudo jogos) simplesmente se recusam a funcionar se a memória virtual estiver desativada. O pagefile deve ser usado para algo do tipo "debug" para os programas, filtrando informações ou algo assim.

    Humm... eu já li sobre isso em algum livro que eu tenho aqui...
  8. Marcelo de Matos Soeiro
    Bom, não estou lembrado direito da sintaxe, mas, para mudar as prioridades dos processos, são usados os comandos nice e renice. Olha a man page deles e veja se consegue o que deseja.
    Prioridades negativas (até -10, se não me engano) são maiores e positivas (até 10) dão menos prioridade. Aliás, acho que o top mostra, em alguma coluna, a prioridade, que pode ser mudada.
    Mas, se o kurumim@0625 encontrar antes, tenho certeza de que ele posta aqui. :D

    Fiquem com Deus.
  9. Juca13
    Sobre a prioridade dos programas, dá uma olhada aqui.
  10. /-//_/(¬( )
    Como por linha de comando saber apenas a memória utilizada sem contar os buffers+cache? até agora não achei nenhum parâmetro do free para isso.
  11. angeloshimabuko
    Olhe a terceira linha da saída do comando "free". Os valores listados correspondem à quantidade de memória usada e livre, respectivamente, desconsiderados os valores relativos a buffers e cache.

    À medida que a memória livre vai se esgotando, o Linux vai reduzindo a quantidade utilizada pelos buffers e cache. Quando não é mais possível, i.e., não existe mais memória livre suficiente, e tenta-se abrir uma nova aplicação, ou uma aplicação corrente solicita mais memória, essas operações serão abortadas.

    Isso irá ocorrer independentemente da existência ou não do espaço de swap. Sempre é possível utilizar toda a memória disponível (RAM + swap).

    Quando falta memória, existem 2 opções: (i) aumentar a quantidade de RAM; (ii) aumentar (ou criar) um espaço de swap - pode-se fazer isso sem reiniciar o Linux, bastar criar um arquivo de swap (p.ex., com 128 MiB):
    Código (Text):
    # dd if=/dev/zero of=/caminho/para/arquivo-swap bs=1024 count=131072
    # mkswap /caminho/para/arquivo-swap
    # swapon /caminho/para/arquivo-swap
    Não entendi o que você quis dizer com "excedente".
  12. Marcelo de Matos Soeiro
    Pelo que eu entendi, Angeloshimabuko, ele não executará o aplicativo... mas, ficou claro que, ele só faz isso quando a memória realmente acaba, ou seja, não tem mais cache de disco e não pode fechar mais nada, pois o que está na memória está efetivamente em execução. Tem sentido. Obridado pela resposta, meu querido, muito elucidativo.
    Fique com Deus.
  13. jqueiroz
    Movido para a sala "Linux: Suporte a Hardware", fixado. :bom_trabalho:
  14. sifion
    mto bom!!! parabens!!!

    alguém sabe me dizer, que diretivas o sistema usa para a alocação de memória swap? quer dizer, se o sistema já está utilizando toda a memória física e mais uma parte da swap... q critérios o sistema utiliza para decidir qual informação vai para a swap e qual vai para a memória física?

    abraço...
  15. jqueiroz
    O sistema de memória virtual funciona por paginação. Cada processo tem uma coleção de páginas de memória, que podem estar carregadas na memória física ou salvas no swap.

    Sempre que um processo tenta acessar uma página que não está carregada e não há página livre na memória física, o kernel vê, dentre os vários processos em execução e com páginas carregadas, qual tem a página que está há mais tempo sem ser acessada (LRU), e a move para o swap. Em seguida, carrega a página solicitada do swap e aloca a página física para o processo em questão.
  16. angeloshimabuko
    Primeiro, para facilitar o entendimento, seja a seguinte nomenclatura: (i) a memória física principal (RAM) é dividida em blocos chamados molduras de página (page frames); (ii) o espaço ocupado por um processo é dividido em blocos chamados páginas (pages). Assim, uma página pode ou não estar contida em uma moldura, i.e., pode ou não estar na memória principal.

    No Linux, o algoritmo utilizado para atender às solicitações de memória feitas pelos processos (aplicações) chama-se page frame reclaiming algorithm - PFRA. Esse algoritmo foi desenhado para permitir a alocação de molduras de página em várias situações: muita memória disponível, pouca memória disponível e situação crítica (quando não é possível alocar molduras para um determinado processo). Como o jqueiroz já citou, esse algorimo baseia-se numa método chamado LRU (least recently used - menos recentemente usado).

    Simplificadamente, método LRU é implementado usando-se duas listas encadeadas: (i) inactive_list e (ii) active_list. Quando uma página, ao ser varrida pelo gerenciador de memória (mm), é identificada como inativa, uma marca (flag) é colocada na respectiva tabela de páginas; se receber duas marcas, irá para a lista inactive_list. Quando o gerenciador de memória (normalmente um serviço do kernel denominado kswapd) necessita de memória, irá escolher as molduras que estão no fim da lista para transferir seu conteúdo para o espaço de troca (swap space).

    O algoritmo PFRA leva em consideração vários fatores para paginação, tais como se a página está compartilhada entre vários processos, se pertence ao buffer ou à cache, se é reservada, etc.

    Se uma condição crítica ocorre, i.e., não é possível alocar uma moldura de página para um processo, e o espaço de troca também está totalmente ocupado, o kernel utiliza uma função chamada out of memory killer, que irá escolher um processo e matá-lo, para liberar suas páginas. Essa escolha não é aleatória, e utiliza certos parâmetros, como: não pode ser uma kernel thread, o processo init (pid 1) ou o swapper (pid 0); não deve ser um processo que esteja acessando determinados tipos de hardware, como o servidor X; não deve ser um processo iniciado pelo root; e assim por diante.

    Em condições normais o processo kswapd irá tentar manter um certo número de molduras disponíveis - esse número normalmente estará entre dois valores - pages_low e pages_high - calculados a partir de outro valor, chamado pages_min (pages_low = (5/4) * pages_min e pages_high = (3/2) * pages_min) que é determinado na inicialização do kernel e que depende da quantidade de memória física instalada.
  17. sifion
    eu esperando um comentário simples, e vem logo um tuto sobre o assunto...

    valeu!!!

    fica tb a sugestão para adicionar essas informações no post original, acho q acrescenta bem ao tema...

    abraço...
  18. wuemura
    Não sei como funciona nas outras distribuições, mas em distribuições baseadas em Red Hat não é necessário fazer o comando echo "20" > /proc/sys/vm/swappiness, que é uma herança do 2.2 e 2.4 :D

    Todas as opções estão disponíveis via sysctl, por exemplo:
    Código (Text):
    [root@tompc etc]# sysctl -A|grep swappiness
    vm.swappiness = 10
    Agora adicione o comando no /etc/sysctl.conf, ex:
    Código (Text):
    vm.swappiness = 10
  19. emtudo
    ótima dica...
    so me trouxe confusao no topico se era uma pergunta ou uma dica, se vc editar e colocar "[dica]" antes no titulo do topico fica mais facil de entender?

    mas ficou otimo, bom eu gostei...

    eu tenho 2025 Giga de memoria fisica, e o meu arquivo tinha um valor de 60, foi bom, pq eu tinha estranhando uma certa vez ele usar a swap ao inves de deletar arquivos do cache. mas agora eu acho que entendi, coloquei apenas 20 neste arquivo, para diminuir a prioridade da swap
  20. mahapra
    Pessoal desculpem colocar mais uma pergunta aqui após 95 dias de inatividade deste tópico mas é que acho que vai completar este assunto se pudermos encerrar falando algo sobre os buffers e também sobre o comando vmstat.

    Abaixo mostro a saida de um comando "vmstat" o qual exibe 03 situações da RAM em intervalos de 1 segundo.

    Tenho 512MB/RAM com 1GB de partição de swap. Podemos ver que 209,232MB esta sendo usado como cache (cache de disco). Como já foi explicado acima, isso é útil pois agiliza muito a recarga de programas usados recentemente, caso contrário teriam que ser lidos novamente no disco ou na partição de swap.

    A questão é : Pra que serve aquela parte destinada a buffers ?
    seriam por acaso buffers de arquivos abertos? ou o que mais?


    Código (Text):

    :$ vmstat 1 3
    procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
     r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
     0  0      0 209020  15028 209232    0    0    36     9  378  185  3  0 96  1
     0  0      0 209020  15028 209232    0    0     0     0  359  237  1  0 99  0
     0  0      0 209020  15036 209224    0    0     0    12  354  212  0  0 100  0

    Descrição dos campos:
    r: The number of processes waiting for run time.
    b: The number of processes in uninterruptible sleep.

    swpd:   quantidade de memória virtual usada
    free:   quantidade de memória livre
    buff:   quantidade de memória usada como buffers
    cache:  quantidade de memória usada como cache
    inact:  quantidade de memória inativa (exibido com a opção -a)
    active: quantidade de memória ativa   (exibido com a opção -a)

    si: "swapped in"  quantidade de memória trazida do swap em disco.
    so: "swapped out" quantidade de memória armazenada no swap em disco.

     
    Outro teste: Eu judiei, abri trocentas janelas de aplicativos pra ver se o bicho abria o bico... mas mesmo assim, é muito difícil ver alguma indicação de uso da área de swap, parece que os 512MB dão conta do recado sem precisar recorrer ao swap em disco!!!
    " Êta gerenciamento bão! " :cap_feceiro:

    agradeço a todos!