fragmentação da memória do Linux

19

Existe uma maneira de detectar a fragmentação de memória no linux? Isso porque, em alguns servidores de longa execução, notei a degradação do desempenho e, somente depois de reiniciar o processo, vejo um melhor desempenho. Eu notei mais quando usando o suporte de página enorme linux - são enormes páginas no linux mais propensas a fragmentação?

Eu olhei para / proc / buddyinfo em particular. Eu quero saber se existem maneiras melhores (não apenas os comandos da CLI em si, qualquer programa ou plano de fundo teórico) para examiná-lo.

    
por Raghu 16.04.2010 / 11:03

3 respostas

11

Estou respondendo à tag . Minha resposta é específica apenas para Linux .

Sim, páginas enormes são mais propensas a fragmentação. Existem duas visões de memória, aquela que seu processo obtém (virtual) e aquela que o kernel gerencia (real). Quanto maior for qualquer página, mais difícil será agrupar (e manter) os vizinhos, especialmente quando o serviço estiver sendo executado em um sistema que também tenha que suportar outros que, por padrão, alocam e gravam mais memória do que na verdade acabam usando.

O mapeamento do kernel de endereços concedidos (reais) é privado. Há uma boa razão pela qual o userspace os vê como o kernel os apresenta, porque o kernel precisa ser capaz de supercomprimir sem confundir o espaço do usuário. O seu processo obtém um espaço de endereçamento contíguo, "Disneyfied" , no qual trabalhar, alheio ao que o kernel está realmente fazendo com essa memória nos bastidores.

O motivo pelo qual você vê desempenho degradado em servidores de longa execução é mais provável porque os blocos alocados que não foram explicitamente bloqueados (por exemplo, mlock() / mlockall() ou posix_madvise() ) e não modificados em um tempo foram paginou , o que significa que o seu serviço desliza para o disco quando é necessário lê-lo. Modificar esse comportamento torna seu processo um vizinho ruim , e é por isso que muitas pessoas colocam seu RDBMS em um servidor completamente diferente de web / php / python / ruby / whatever. A única maneira de consertar isso, no mínimo, é reduzir a competição por blocos contíguos.

A fragmentação só é realmente perceptível (na maioria dos casos) quando a página A está na memória e a página B foi movida para swap. Naturalmente, reiniciar seu serviço pareceria "curar" isso, mas somente porque o kernel ainda não teve a oportunidade de mostrar o processo (agora) recém alocados blocos dentro dos limites de sua taxa de supercomprometimento.

Na verdade, reiniciar (digamos) o 'apache' sob uma carga alta provavelmente enviará blocos de propriedade de outros serviços diretamente para o disco. Então, sim, o 'apache' melhoraria por um curto período de tempo, mas o 'mysql' poderia sofrer ... pelo menos até que o kernel faça com que sofram igualmente quando houver simplesmente falta de memória física suficiente.

Adicione mais memória ou divida-se exigindo malloc() consumidores :) Não é apenas a fragmentação que você precisa analisar.

Teste vmstat para obter uma visão geral do que realmente está sendo armazenado.

    
por 16.04.2010 / 12:52
4

O uso de páginas enormes não deve causar fragmentação de memória extra no Linux; O suporte do Linux para páginas grandes é somente para memória compartilhada (via shmget ou mmap), e qualquer página grande usada deve ser especificamente solicitada e pré-alocada por um administrador do sistema. Uma vez na memória, eles são fixados lá e não são trocados. O desafio de trocar páginas enormes diante da fragmentação de memória é exatamente o motivo pelo qual elas permanecem fixas na memória (ao alocar uma página enorme de 2 MB, o kernel precisa encontrar 512 páginas 4KB contíguas, que podem nem existir).

Documentação do Linux em páginas enormes: link

Há uma circunstância em que a fragmentação de memória pode causar lentidão na alocação de páginas enormes (mas não em locais onde páginas enormes causam fragmentação de memória), e isso se o sistema estiver configurado para aumentar o pool de páginas enormes se solicitado por um aplicativo. Se / proc / sys / vm / nr_overcommit_hugepages for maior que / proc / sys / vm / nr_hugepages, isso pode acontecer.

    
por 02.03.2011 / 21:46
4

Kernel

Para obter o uso atual do índice de fragmentação:

sudo cat /sys/kernel/debug/extfrag/extfrag_index

Para desfragmentar a memória do kernel, tente executar:

sysctl vm.compact_memory=1  

Você também tenta desativar o Transparent Huge Pages (também conhecido como THP) e / ou desativar o swap (ou diminuir o swappiness ).

Espaço do usuário

Para reduzir a fragmentação do espaço de usuário, convém tentar um alocador diferente, por exemplo, jemalloc (tem grandes recursos de introspecção , que lhe darão uma dentro da fragmentação interna do alocador).

Você pode alternar para o malloc personalizado recompilando seu programa com ele ou apenas executando o programa com LD_PRELOAD : LD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app (cuidado com interações entre THP e alocadores de memória de memória )

Embora, pouco relacionado à fragmentação de memória (mas conectado à compactação / migração de memória), você provavelmente desejará executar várias instâncias do seu serviço, uma para cada nó NUMA e vinculá-las usando numactl .

    
por 30.12.2015 / 23:49