Este é um post antigo, no entanto, eu ainda teria a liberdade de colocar meus pensamentos aqui.
Começando de baixo, o Linux primeiro dividia a memória em páginas (geralmente 4K por página no sistema x86_64). Depois disso, a memória virtual é criada, cujo mapeamento é feito com memória física usando a MMU (Unidade de Gerenciamento de Memória).
Os processos recebem memória alocada da área de memória virtual; portanto, observe que, quando você vê / proc / meminfo, verá o VMalloc * como os detalhes da memória virtual.
Digamos que você tenha um processo que solicite memória (digamos 300 MB - um navegador da web). O processo seria alocado a 300 MB da memória virtual; no entanto, não é necessário que a memória seja mapeada (que é mapeada para a memória física). Existe o conceito de "Copiar na gravação" para gerenciamento de memória, pelo qual, se seus processos realmente usarem a memória alocada na memória virtual (isto é, alguns gravam na memória), somente então eles serão mapeados para a memória física. Isso ajuda o kernel a funcionar corretamente em um ambiente de múltiplos processos com eficiência.
O que são cache?
Muita memória usada pelos processos é compartilhada. Digamos que a biblioteca glibc seja usada por quase todos os processos. Qual é o objetivo de manter várias cópias da glibc na memória, quando todo processo pode acessar o mesmo local da memória e fazer o trabalho. Esses recursos usados com freqüência são mantidos em cache para que, quando os processos exigirem, possam ser referenciados no mesmo local da memória. Isso ajuda a acelerar os processos, pois a leitura do glibc (etc.) De novo e de novo do disco seria demorada.
O exemplo acima foi para bibliotecas compartilhadas, por exemplo, semelhante também é válido para a leitura de arquivos. Se você ler um arquivo grande (digamos 100-200MB) pela primeira vez, levará muito tempo. No entanto, quando você tenta fazer a mesma leitura novamente, seria mais rápido. Os dados foram armazenados em cache na memória e a releitura não foi realizada para todos os blocos.
O que é buffer?
No que diz respeito ao buffer, quando um processo arquiva E / S, ele depende do buffer do kernel para gravar dados no disco. Os processos solicitam que o kernel faça o trabalho. Portanto, em nome do processo, o kernel grava os dados em seu "buffer" e informa ao processo que a gravação está concluída. De maneira assíncrona, o kernel continuará sincronizando esses dados no buffer para o disco. Dessa forma, os processos contam com o kernel para escolher um horário correto para sincronizar os dados no disco, e os processos podem continuar trabalhando adiante. Lembre-se, é a E / S geral que os processos normais estão executando. No entanto, processos especializados, que precisam confirmar que a E / S é realmente feita no disco, podem usar outro mecanismo para executar a E / S no disco. Alguns utilitários de código-fonte aberto são libaio. Além disso, existem maneiras de chamar a sincronização explícita para os FDs abertos no seu contexto de processos,
O que são falhas de página então?
Considere um exemplo, quando você inicia um processo (por exemplo, um navegador da web), cujo binário é de cerca de 300 MB. No entanto, os 300 MB completos do binário do navegador da Web não começam a funcionar instantaneamente. O processo continua passando de funções para funções em seu código. Como dito anteriormente, a memória virtual seria consumida em 300 MB, no entanto, nem toda a memória é mapeada para a memória física (RSS - a memória residente seria menor, consulte a saída principal). Quando a execução do código atinge um ponto, para o qual a memória não é realmente mapeada fisicamente, haveria uma falha na página. O kernel mapeia essa memória para física, associa a página de memória ao seu processo. Essa falha de página é chamada de "Falhas secundárias na página". Da mesma forma, quando um processo está executando as principais falhas de página de E / S do arquivo, são levantadas.
Quando e por que o Swap Out acontece?
Situação 1:
De acordo com os detalhes acima, vamos considerar um cenário em que a boa quantidade de memória se torna mapeada na memória. E agora um processo é iniciado, o que requer memória. Como discutido acima, o kernel precisará fazer algum mapeamento de memória. No entanto, não há RAM física suficiente disponível para mapear a memória. Agora, o kernel examinará primeiro o cache, terá algumas páginas de memória antigas que não estão sendo usadas. Ele liberará essas páginas em uma partição separada (chamada SWAP), liberará algumas páginas e mapeará as páginas liberadas para a nova solicitação. Como a gravação em disco é muito mais lenta que a RAM de estado sólido, esse processo leva muito tempo e, portanto, é observada uma lentidão.
Situação 2:
Digamos que você veja muita memória livre disponível no sistema. Mesmo assim, você vê que há muita troca acontecendo. Pode haver um problema provável de fragmentação da memória. Considere um processo que exige 50 MB de memória contígua do kernel. (tenha em mente contíguo). Obviamente, o kernel teria alocado páginas aleatoriamente para diferentes processos e liberado algumas delas. No entanto, quando exigimos memória contígua, ela deve procurar um pedaço que satisfaça a demanda dos processos. Se não conseguir obter essa memória, será necessário trocar algumas páginas antigas de memória e depois alocar páginas contíguas. Mesmo nesses casos, o SWAP out aconteceria. Iniciando o Kernel ver 2.6 e acima, esses problemas de fragmentação reduziram consideravelmente. No entanto, se o sistema estiver em execução por um longo período, esses problemas ainda poderão surgir.
Veja este exemplo ( saída vmstat )
2016-10-29 03:55:32 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2016-10-29 03:55:32 r b swpd free buff cache si so bi bo in cs us sy id wa st
2016-10-30 03:56:04 19 23 2914752 4692144 3344908 12162628 1660 1 8803 12701 4336 37487 14 7 40 38 0
2016-10-30 03:56:34 3 20 2889296 4977580 3345316 12026752 2109 2 8445 14665 4656 36294 12 7 46 34 0
2016-10-30 03:57:04 1 11 3418868 4939716 3347804 11536356 586 4744 2547 9535 3086 24450 6 3 59 33 0 <<<-----
2016-10-30 03:57:34 3 19 3456252 5449884 3348400 11489728 3291 13371 6407 17957 2997 22556 6 4 66 24 0
2016-10-30 03:58:04 7 6 4194500 5663580 3349552 10857424 2407 12240 3824 14560 2295 18237 4 2 65 29 0
2016-10-30 03:58:34 2 16 4203036 5986864 3348908 10838492 4601 16639 7219 18808 2575 21563 6 4 60 31 0
2016-10-30 03:59:04 3 14 4205652 6059196 3348760 10821448 6624 1597 9431 4357 1750 20471 6 2 60 31 0
2016-10-30 03:59:34 2 24 4206968 6053160 3348876 10777216 5221 2067 10106 7377 1731 19161 3 3 62 32 0
2016-10-30 04:00:04 0 13 4205172 6005084 3348932 10785896 6236 1609 10330 6264 1739 20348 4 2 67 26 0
2016-10-30 04:00:34 4 11 4206420 5996396 3348976 10770220 6554 1253 10382 4896 1964 42981 10 5 58 27 0
2016-10-30 04:01:04 6 4 4177176 5878852 3348988 10825840 8682 765 10126 2716 1731 32949 8 4 69 19 0
@ 2016-10-30 03:57:04, vemos que ainda há uma boa quantidade de RAM livre disponível. No entanto, mesmo assim, a troca aconteceu. Verificamos a árvore do processo neste momento e não vimos nenhum processo que demandasse uma quantidade tão alta de memória (mais do que memória livre). A suspeita óbvia foi a Situação 2 descrita acima. Verificamos os logs buddyinfo e zoneinfo acima (Use echo m> / proc / sysrq-trigger para verificá-los, a saída entra em syslogs).
Para um sistema normal, a comparação das informações da zona é a seguinte. E gráficos para cache / memória livre / baixa também são mencionados abaixo
Observando as informações, fica claro que há fragmentação da memória no nó 0 e no nó 1 normal (o nó é uma máquina baseada em NUMA, portanto, vários nós (consulte numactl para verificar as informações do seu sistema)).
A fragmentação da memória também é uma razão pela qual o uso de swap pode aumentar mesmo quando há memória livre.