Eu achei que pidstat
seria uma boa ferramenta para monitorar processos. Quero calcular o uso médio de memória de um processo específico. Aqui está um exemplo de saída:
02:34:36 PM PID minflt/s majflt/s VSZ RSS %MEM Command
02:34:37 PM 7276 2.00 0.00 349212 210176 7.14 scalpel
(Isso faz parte da saída de pidstat -r -p 7276
.)
Devo usar as informações de tamanho do conjunto residente (RSS) ou tamanho virtual (VSZ) para calcular o consumo médio de memória? Eu li algumas coisas na Wikipedia e em fóruns, mas não tenho certeza de entender completamente as diferenças. Além disso, parece que nenhum deles é confiável. Então, como posso monitorar um processo para obter seu uso de memória?
Qualquer ajuda sobre este assunto seria útil.
Respostas:
RSS é a quantidade de memória que esse processo tem atualmente na memória principal (RAM). VSZ é a quantidade de memória virtual que o processo possui no total. Isso inclui todos os tipos de memória, tanto na RAM quanto trocados. Esses números podem ficar distorcidos porque também incluem bibliotecas compartilhadas e outros tipos de memória. Você pode ter quinhentas instâncias em
bash
execução, e o tamanho total da área ocupada por memória não será a soma dos valores RSS ou VSZ.Se você precisar obter uma idéia mais detalhada sobre o espaço ocupado por memória de um processo, terá algumas opções. Você pode
/proc/$PID/map
eliminar e eliminar as coisas que não gosta. Se forem bibliotecas compartilhadas, o cálculo pode ficar complexo dependendo de suas necessidades (das quais acho que me lembro).Se você se importa apenas com o tamanho da pilha do processo, sempre pode analisar a
[heap]
entrada nomap
arquivo. O tamanho que o kernel alocou para o heap do processo pode ou não refletir o número exato de bytes que o processo solicitou para ser alocado. Existem detalhes minuciosos, detalhes internos do kernel e otimizações que podem desencadear isso. Em um mundo ideal, será o máximo que seu processo precisa, arredondado para o múltiplo mais próximo do tamanho da página do sistema (getconf PAGESIZE
dirá o que é - nos PCs, são provavelmente 4.096 bytes).Se você deseja ver quanta memória um processo alocou , uma das melhores maneiras é renunciar às métricas do lado do kernel. Em vez disso, você instrumenta as funções de (des) alocação de memória heap da biblioteca C com o
LD_PRELOAD
mecanismo. Pessoalmente, eu abusei um poucovalgrind
para obter informações sobre esse tipo de coisa. (Observe que a aplicação da instrumentação exigirá reiniciar o processo.)Observe que, como você também pode comparar tempos de execução, isso
valgrind
tornará seus programas um pouco mais lentos (mas provavelmente dentro de suas tolerâncias).fonte
/proc/$PID/maps
é diferença de erro de digitação ou distribuição?Exemplo mínimo executável
Para que isso faça sentido, é necessário entender o básico da paginação: https://stackoverflow.com/questions/18431261/how-does-x86-paging-work e, em particular, que o sistema operacional pode alocar memória virtual por meio de tabelas de páginas / sua manutenção de livro de memória interna (memória virtual VSZ) antes que ele realmente tenha um armazenamento de backup na RAM ou no disco (memória residente em RSS).
Agora, para observar isso em ação, vamos criar um programa que:
mmap
main.c
GitHub upstream .
Compile e execute:
Onde:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
: necessário para o Linux nos permitir fazer uma chamada mmap maior que a RAM física: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate/57687432#57687432Saída do programa:
Status de saída:
que pela regra do número de sinal 128 + significa que obtivemos o número do sinal
9
, queman 7 signal
é SIGKILL , enviado pelo assassino de memória insuficiente do Linux .Interpretação de saída:
printf '0x%X\n' 0x40009A4 KiB ~= 64GiB
(osps
valores estão em KiB) após o mmap.extra_memory_committed 0
, o que significa que ainda não tocamos em nenhuma página. RSS é um pequeno1648 KiB
que foi alocado para a inicialização normal do programa, como área de texto, globais, etc.8388608 KiB == 8GiB
valor de páginas. Como resultado, o RSS aumentou exatamente 8GIB para8390256 KiB == 8388608 KiB + 1648 KiB
Consulte também: Precisa de explicação sobre o tamanho do conjunto residente / tamanho virtual
Logs assassinos de OOM
Nossos
dmesg
comandos mostraram os logs do OOM killer.Uma interpretação exata deles foi solicitada em:
A primeira linha do log foi:
Portanto, vemos que, curiosamente, foi o daemon MongoDB que sempre roda no meu laptop em segundo plano, o que desencadeou o assassino do OOM, provavelmente quando o pobre estava tentando alocar alguma memória.
No entanto, o assassino da OOM não mata necessariamente quem o acordou.
Após a chamada, o kernel imprime uma tabela ou processos, incluindo
oom_score
:e mais adiante, vemos que nosso pouco
main.out
foi morto na invocação anterior:Esse registro menciona o
score 865
que esse processo teve, presumivelmente a maior (pior) pontuação do assassino da OOM, conforme mencionado em: Como o assassino da OOM decide qual processo matar primeiro?Curiosamente, tudo aparentemente aconteceu tão rápido que, antes que a memória liberada fosse contabilizada, ela
oom
foi despertada novamente peloDeadlineMonitor
processo:e desta vez que matou algum processo do Chromium, que geralmente é a memória normal de meus computadores:
Testado no Ubuntu 19.04, kernel do Linux 5.0.0.
fonte