O valor de troca do Linux não tem nada a ver com a quantidade de RAM usada antes do início da troca. Esse é um erro amplamente divulgado e amplamente aceito. Explicamos o que realmente é.
Índice
Rebentando mitos sobre troca
A troca é uma técnica em que os dados na memória de acesso aleatório (RAM) são gravados em um local especial no disco rígido – uma partição de troca ou um arquivo de troca – para liberar RAM.
O Linux tem uma configuração chamada valor de troca. Há muita confusão sobre o que essa configuração controla. A descrição incorreta mais comum de troca é que ela define um limite para o uso de RAM e, quando a quantidade de RAM usada atinge esse limite, a troca começa.
Este é um equívoco que tem sido repetido tantas vezes que agora é uma sabedoria aceita. Se (quase) todo mundo diz que é exatamente assim que funciona a troca, por que você deveria acreditar em nós quando dizemos que não é?
Simples. Vamos provar isso.
Sua RAM está dividida em zonas
O Linux não pensa em sua RAM como um grande conjunto homogêneo de memória. Ele considera que está dividido em várias regiões diferentes chamadas zonas. As zonas presentes em seu computador dependem se ele é de 32 ou 64 bits . Aqui está uma descrição simplificada das zonas possíveis em um computador de arquitetura x86 .
- Acesso direto à memória (DMA) : São os poucos 16 MB de memória. A zona tem esse nome porque, há muito tempo, havia computadores que só podiam fazer o acesso direto à memória para essa área da memória física.
- Direct Memory Access 32 : Apesar do nome, Direct Memory Access 32 (DMA32) é uma zona encontrada apenas no Linux de 64 bits. São os poucos 4 GB de memória. O Linux em execução em computadores de 32 bits só pode fazer DMA para essa quantidade de RAM (a menos que estejam usando o kernel de extensão de endereço físico (PAE)), que é como a região recebeu seu nome. Embora, em computadores de 32 bits, seja denominado HighMem.
- Normal : em computadores de 64 bits, a memória normal é toda a RAM acima de 4 GB (aproximadamente). Em máquinas de 32 bits, é RAM entre 16 MB e 896 MB.
- HighMem : só existe em computadores Linux de 32 bits. É toda RAM acima de 896 MB, incluindo RAM acima de 4 GB em máquinas suficientemente grandes.
O valor PAGESIZE
A RAM é alocada em páginas de tamanho fixo. Esse tamanho é determinado pelo kernel no momento da inicialização, detectando a arquitetura do computador. Normalmente, o tamanho da página em um computador Linux é de 4 Kbytes.
Você pode ver o tamanho da página usando o getconf
comando :
getconf PAGESIZE
Zonas são anexadas a nós
As zonas são anexadas aos nós. Os nós são associados a uma Unidade de Processamento Central (CPU) . O kernel tentará alocar memória para um processo em execução em uma CPU a partir do nó associado a essa CPU.
O conceito de nós vinculados a CPUs permite que tipos de memória mistos sejam instalados em computadores multi-CPU especializados, usando a arquitetura Non-Uniform Memory Access .
Isso tudo é muito sofisticado. O computador Linux médio terá um único nó, denominado nó zero. Todas as zonas pertencerão a esse nó. Para ver os nós e zonas em seu computador, olhe dentro do /proc/buddyinfo
arquivo. Usaremos less
para fazer isso:
menos / proc / buddyinfo
Esta é a saída do computador de 64 bits em que este artigo foi pesquisado:
Nó 0, zona DMA 1 1 1 0 2 1 1 0 1 1 3 Nó 0, zona DMA32 2 67 58 19 8 3 3 1 1 1 17
Existe um único nó, nó zero. Este computador possui apenas 2 GB de RAM, portanto, não há zona “Normal”. Existem apenas duas zonas, DMA e DMA32.
Cada coluna representa o número de páginas disponíveis de um determinado tamanho. Por exemplo, para a zona DMA32, lendo da esquerda:
- 2 : Existem 2 de 2 ^ ( 0 * PAGESIZE) blocos de memória.
- 67 : Há 67 de 2 ^ ( 1 * PAGE_SIZE) blocos de memória.
- 58 : Existem 58 de 2 ^ ( 2 * PAGESIZE) blocos de memória disponíveis.
- E assim por diante, até …
- 17 : Existem 17 de 2 ^ ( 512 * PAGESIZE) pedaços.
Mas, na verdade, o único motivo pelo qual estamos examinando essas informações é para ver a relação entre nós e zonas.
Páginas de arquivo e páginas anônimas
O mapeamento de memória usa conjuntos de entradas de tabela de página para registrar quais páginas de memória são usadas e para quê.
Os mapeamentos de memória podem ser:
- Arquivo de backup : mapeamentos de arquivo contém dados que foram lidos de um arquivo. Pode ser qualquer tipo de arquivo. O importante a notar é que se o sistema liberou essa memória e precisou obter os dados novamente, eles podem ser lidos do arquivo mais uma vez. Mas, se os dados foram alterados na memória, essas alterações precisarão ser gravadas no arquivo do disco rígido antes que a memória seja liberada. Se isso não acontecesse, as mudanças seriam perdidas.
- Anônimo : a memória anônima é um mapeamento de memória sem nenhum arquivo ou dispositivo como suporte. Essas páginas podem conter memória solicitada em tempo real por programas para armazenar dados ou para coisas como pilha e heap . Como não há nenhum arquivo por trás deste tipo de dados, um local especial deve ser reservado para o armazenamento de dados anônimos. Esse local é a partição ou arquivo de troca. Os dados anônimos são gravados para trocar antes que as páginas anônimas sejam liberadas.
- Dispositivo de backup : os dispositivos são endereçados por meio de arquivos de dispositivo de bloco que podem ser tratados como se fossem arquivos . Os dados podem ser lidos e gravados neles. Um mapeamento de memória com backup de dispositivo contém dados de um dispositivo armazenados nele.
- Compartilhado : Múltiplas entradas de tabela de página podem mapear para a mesma página de RAM. Acessar os locais de memória por meio de qualquer um dos mapeamentos mostrará os mesmos dados. Processos diferentes podem se comunicar uns com os outros de maneira muito eficiente, alterando os dados nesses locais de memória observados em conjunto. Os mapeamentos graváveis compartilhados são um meio comum de obter comunicações entre processos de alto desempenho.
- Cópia na gravação : a cópia na gravação é uma técnica de alocação preguiçosa. Se uma cópia de um recurso já na memória for solicitada, a solicitação será satisfeita retornando um mapeamento para o recurso original. Se um dos processos “compartilhando” o recurso tentar gravar nele, o recurso deve ser verdadeiramente replicado na memória para permitir que as alterações sejam feitas na nova cópia. Portanto, a alocação de memória ocorre apenas no primeiro comando de gravação.
Para a troca, precisamos apenas nos preocupar com os dois primeiros na lista: páginas de arquivo e páginas anônimas.
Troca
Esta é a descrição de troca da documentação do Linux no GitHub :
"This control is used to define how aggressive (sic) the kernel will swap memory pages. Higher values will increase aggressiveness, lower values decrease the amount of swap. A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.
The default value is 60."
Isso soa como a troca de mudanças para cima ou para baixo em intensidade. Curiosamente, ele afirma que definir a troca para zero não desativa a troca. Ele instrui o kernel a não trocar até que certas condições sejam atendidas. Mas a troca ainda pode ocorrer.
Vamos cavar mais fundo. Aqui está a definição e o valor padrão de vm_swappiness
no arquivo de código-fonte do kernel vmscan.c :
/*
* From 0 .. 100. Higher means more swappy.
*/
int vm_swappiness = 60;
O valor de troca pode variar de 0 a 100. Novamente, o comentário certamente soa como se o valor de troca influencia na quantidade de troca que ocorre, com um valor mais alto levando a mais troca.
Mais adiante, no arquivo de código-fonte, podemos ver que uma nova variável chamada swappiness
recebe um valor que é retornado pela função mem_cgroup_swappiness()
. Um pouco mais de rastreamento através do código-fonte irá mostrar que o valor retornado por esta função é vm_swappiness
. Portanto, agora, a variável swappiness
está definida para ser igual a qualquer valor vm_swappiness
definido para.
int swappiness = mem_cgroup_swappiness(memcg);
E um pouco mais abaixo, no mesmo arquivo de código-fonte , vemos isso:
/*
* With swappiness at 100, anonymous and file have the same priority.
* This scanning priority is essentially the inverse of IO cost.
*/
anon_prio = swappiness;
file_prio = 200 - anon_prio;
Isso é interessante. Dois valores distintos são derivados de swappiness
. As variáveis anon_prio
e file_prio
mantêm esses valores. À medida que um aumenta, o outro diminui e vice-versa .
O valor de troca do Linux, na verdade, define a proporção entre dois valores.
The Golden Ratio
As páginas do arquivo contêm dados que podem ser facilmente recuperados se a memória for liberada. O Linux pode simplesmente ler o arquivo novamente. Como vimos, se os dados do arquivo foram alterados na RAM, essas alterações devem ser gravadas no arquivo antes que a página do arquivo seja liberada. Mas, de qualquer forma, a página do arquivo na RAM pode ser preenchida novamente com a leitura dos dados do arquivo. Então, por que se preocupar em adicionar essas páginas à partição ou arquivo de troca? Se você precisar desses dados novamente, também pode lê-los de volta do arquivo original em vez de uma cópia redundante no espaço de troca. Portanto, as páginas do arquivo não são armazenadas na troca. Eles são “armazenados” de volta no arquivo original.
Com páginas anônimas, não há arquivo subjacente associado aos valores na memória. Os valores nessas páginas foram alcançados dinamicamente. Você não pode simplesmente lê-los de volta de um arquivo. A única maneira de recuperar os valores de memória de página anônima é armazenar os dados em algum lugar antes de liberar a memória. E é isso que a troca vale. Páginas anônimas que você precisará consultar novamente.
Mas observe que, tanto para páginas de arquivo quanto para páginas anônimas, a liberação de memória pode exigir uma gravação no disco rígido. Se os dados da página do arquivo ou os dados da página anônima foram alterados desde a última vez que foram gravados no arquivo ou para troca, uma gravação do sistema de arquivos é necessária. Para recuperar os dados, será necessária uma leitura do sistema de arquivos. Ambos os tipos de recuperação de página são caros. Tentar reduzir a entrada e saída do disco rígido minimizando a troca de páginas anônimas apenas aumenta a quantidade de entrada e saída do disco rígido necessária para lidar com páginas de arquivo sendo gravadas e lidas de arquivos.
Como você pode ver no último trecho de código, existem duas variáveis. Um chamava file_prio
de “prioridade de arquivo” e outro chamava anon_prio
de “prioridade anônima”.
- A
anon_prio
variável é definida para o valor de troca do Linux. - O
file_prio
valor é definido como 200 menos oanon_prio
valor.
Essas variáveis contêm valores que funcionam em conjunto. Se ambos forem definidos como 100, eles são iguais. Para quaisquer outros valores, anon_prio
diminuirá de 100 para 0 e file_prio
aumentará de 100 para 200. Os dois valores alimentam um algoritmo complicado que determina se o kernel do Linux é executado com preferência para recuperar (liberar) páginas de arquivo ou páginas anônimas.
Você pode pensar file_prio
na disposição do sistema de liberar páginas de arquivo e anon_prio
na disposição do sistema de liberar páginas anônimas. O que esses valores não fazem é definir qualquer tipo de gatilho ou limite para quando a troca será usada. Isso é decidido em outro lugar.
Mas, quando a memória precisa ser liberada, essas duas variáveis - e a proporção entre elas – são levadas em consideração pelos algoritmos de recuperação e troca para determinar quais tipos de página são preferencialmente considerados para liberação. E isso determina se a atividade do disco rígido associada processará arquivos para páginas de arquivo ou espaço de troca para páginas anônimas.
Quando a troca realmente interfere?
Estabelecemos que o valor de troca do Linux define uma preferência para o tipo de páginas de memória que serão verificadas para possível recuperação. Tudo bem, mas algo deve decidir quando a troca será interrompida.
Cada zona de memória tem uma marca d’água alta e uma marca d’água baixa. Esses são valores derivados do sistema. Eles são porcentagens da RAM em cada zona. São esses valores que são usados como os limites do acionador de troca.
Para verificar quais são suas marcas d’água superior e inferior, olhe dentro do /proc/zoneinfo
arquivo com este comando:
menos / proc / zoneinfo
Cada uma das zonas terá um conjunto de valores de memória medidos em páginas. Aqui estão os valores para a zona DMA32 na máquina de teste. A marca d’água baixa é 13966 páginas e a marca d’água alta é 16759 páginas:
- Em condições normais de execução, quando a memória livre em uma zona cai abaixo da marca d’água baixa da zona, o algoritmo de troca começa a varrer as páginas de memória procurando por memória que possa recuperar, levando em consideração os valores relativos de
anon_prio
efile_prio
. - Se o valor de troca do Linux for definido como zero, a troca ocorre quando o valor combinado das páginas do arquivo e das páginas livres é menor que o limite superior.
Portanto, você pode ver que não pode usar o valor de troca do Linux para influenciar o comportamento de troca em relação ao uso de RAM. Simplesmente não funciona assim.
O que deve ser definido como swap?
Isso depende do hardware, da carga de trabalho, do tipo de disco rígido e se o seu computador é um desktop ou um servidor. Obviamente, este não será um tamanho único para todos os tipos de configuração.
E você deve ter em mente que a troca não é usada apenas como um mecanismo para liberar RAM quando você está ficando sem espaço de memória. A troca é uma parte importante de um sistema em bom funcionamento e, sem ela, o gerenciamento lógico da memória se torna muito difícil para o Linux.
Alterar o valor de troca do Linux tem um efeito instantâneo; você não precisa reiniciar. Assim, você pode fazer pequenos ajustes e monitorar os efeitos. O ideal é que você faça isso durante alguns dias, com diferentes tipos de atividade em seu computador, para tentar encontrar o mais próximo possível de uma configuração ideal.
Estes são alguns pontos a serem considerados:
- Tentar “desabilitar a troca” definindo o valor de troca do Linux como zero simplesmente muda a atividade do disco rígido associada à troca para a atividade do disco rígido associada ao arquivo.
- Se você tiver discos rígidos mecânicos antigos, pode tentar reduzir o valor de troca do Linux para evitar a recuperação de página anônima e reduzir a rotatividade da partição de troca. Obviamente, conforme você diminui uma configuração, a outra aumenta. Reduzir a rotatividade de troca provavelmente aumentará a rotatividade do sistema de arquivos. Mas seu computador pode preferir um método em vez de outro. Na verdade, a única maneira de saber com certeza é tentando ver.
- Para servidores de finalidade única, como servidores de banco de dados, você pode obter orientação dos fornecedores do software de banco de dados. Muitas vezes, esses aplicativos têm seu próprio cache de arquivo e rotinas de gerenciamento de memória, com os quais seria melhor confiar. Os fornecedores de software podem sugerir um valor de troca do Linux de acordo com as especificações da máquina e carga de trabalho.
- Para o usuário médio de desktop com hardware razoavelmente recente? Deixe como está.
Como definir o valor de troca do Linux
Antes de alterar seu valor de troca, você precisa saber qual é seu valor atual. Se você quiser reduzir um pouco, a questão é um pouco menos do que o quê? Você pode descobrir com este comando:
cat / proc / sys / vm / swappiness
Para configurar o valor de troca, use o sysctl
comando :
sudo sysctl vm.swappiness = 45
O novo valor é usado imediatamente, nenhuma reinicialização é necessária.
Na verdade, se você reiniciar, o valor de troca retornará ao valor padrão de 60. Quando você terminar de experimentar e decidir sobre o novo valor que deseja usar, pode torná-lo persistente entre reinicializações adicionando-o ao /etc/sysctl.conf
arquivo . Você pode usar o editor de sua preferência. Use o seguinte comando para editar o arquivo com o nano
editor:
sudo nano /etc/sysctl.conf
Quando nano
abrir, role até o final do arquivo e adicione esta linha. Estamos usando 35 como o valor de troca permanente. Você deve substituir o valor que deseja usar.
vm.swappiness = 35
Para salvar suas alterações e sair do nano
, pressione “Ctrl + O”, pressione “Enter” e pressione “Ctrl + Z”.
O gerenciamento de memória é complexo
O gerenciamento de memória é complicado. E é por isso que, para o usuário médio, geralmente é melhor deixar isso para o kernel.
É fácil pensar que você está usando mais RAM do que realmente está. Os utilitários gostam top
e free
podem dar uma impressão errada. O Linux usará RAM livre para uma variedade de propósitos, como cache de disco. Isso eleva artificialmente o número de memória “usada” e reduz o número de memória “livre”. Na verdade, a RAM usada como cache de disco é sinalizada como “usada” e “disponível” porque pode ser recuperada a qualquer momento, muito rapidamente.
Para os não iniciados, pode parecer que a troca não está funcionando ou que o valor da troca precisa ser alterado.
Como sempre, o diabo está nos detalhes. Ou, neste caso, o daemon. O daemon de troca do kernel.