Medindo o uso de RAM de um programa

46

time é um comando brilhante se você quiser descobrir quanto tempo de CPU um determinado comando leva.

Estou à procura de algo semelhante que possa medir o uso máximo de RAM do programa e quaisquer filhos. De preferência, ele deve distinguir entre a memória alocada usada e não utilizada. Talvez ele possa fornecer o uso mediano da memória (portanto, o uso da memória que você deve esperar ao executar por um longo tempo).

Então eu gostaria de fazer:

rammeassure my_program my_args

e obtenha uma saída semelhante a:

Max memory allocated: 10233303 Bytes
Max memory used: 7233303 Bytes
Median memory allocation: 5233303 Bytes

Eu olhei para memusg https://gist.github.com/526585/590293d6527c91e48fcb08edb8de9fd6c88a6d82, mas considero isso um tanto quanto um hack.

Ole Tange
fonte

Respostas:

24

Você pode usar o tstime para medir o uso de memória de alta velocidade (RSS e virtual) de um processo.

Por exemplo:

$ tstime date       
Tue Aug 16 21:35:02 CEST 2011

Exit status: 0

pid: 31169 (date) started: Tue Aug 16 21:35:02 2011
        real   0.017 s, user   0.000 s, sys   0.000s
        rss      888 kb, vm     9764 kb

Ele também suporta um modo de saída mais fácil de analisar ( -t).

maxschlepzig
fonte
Eu gosto disso. Até fez The Right Thing com./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
Ole Tange
3
"Uso da RAM pelo processo" não é um valor bem definido: se houver várias instâncias do mesmo programa em execução, eles compartilharão o executável. A maioria dos programas compartilha glibc(e outras bibliotecas variadas, eles são chamados de "compartilhados" para alguma coisa). Muitos daemons carregam a configuração nos filhos de memória e fork (2), que compartilham os dados de configuração. Depois, existem dados nos buffers readahead / writebehind gerenciados pelo kernel. Além disso, existem serviços que são uma manada de processos pouco acoplados (pense no ambiente da área de trabalho e em todos os applets e itens de segundo plano).
vonbrand
@ vonbrand, como o Linux-Kernel calcula os valores de RSS / VSS está bem definido.
maxschlepzig
@maxschlepzig, pode muito bem calcular alguns valores aleatórios, isso não significa que eles significam o que você pensa que significa: O conjunto residente é apenas as páginas no espaço de endereço do processo que estão atualmente na memória. Essa não é a "memória usada por esse processo", inclui o que estiver compartilhando.
vonbrand
@vonbrand A maioria dos casos de medição de uso de memória de um processo desejará medir páginas anônimas não compartilhadas, o que deve ser muito previsível com a mesma entrada.
Vladimir Panteleev
28

timeé um built-in do seu shell. Se você quiser, timemas precisar de mais informações, tente o GNU timeno modo verbose ( -v):

/usr/bin/time -v sleep 5               
    Command being timed: "sleep 5"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 2144
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 179
    Voluntary context switches: 2
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Pesquise o pacote "time" ou "gnutime" no seu gerenciador de pacotes.

Rufo El Magufo
fonte
3
Observe que algumas informações relatadas pelo tempo do GNU podem ser imprecisas. Por exemplo, no Ubuntu 10.04: A página de manual indica 'Os números são tão bons quanto os retornados por wait3 (2)'. Ou seja, wait3preenche uma estrutura descrita em getrusage(2): 'Nem todos os campos são significativos no Linux. [...]
maxschlepzig
4
Por exemplo, em um programa de teste que aloca exatamente 10 MB (e toca em cada página) - o tempo GNU relata um maxRSS máximo de 42608 KiB - e tstimerelata 10652 KiB. Novamente no Ubuntu 10.04.
maxschlepzig
Eu adoraria se fosse assim tão simples. Na minha máquina Ubuntu eu tentei: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. top diz que leva cerca de 570 MB, mas o tempo diz 2,3 GB. Na prática, esse número não é habitável para mim.
precisa saber é o seguinte
O fator 4 é fixo no tempo GNU 1.7 e, portanto, funciona conforme o esperado.
Ole Tange
Nota importante: O "Tamanho máximo do conjunto de residentes" funciona apenas desde o Linux 2.6.32.
precisa
17

Talvez exagere, mas acabei de descobrir que valgrindtem uma boa ferramenta chamada massif. Eu testei em xterm:

valgrind --trace-children=yes --tool=massif xterm
ms_print massif.out.* | less

E você obtém um bom gráfico de uso de memória:

    MB
4.230^                     #                    :::::::  :::      @@:     ::: 
     |   @                 #:::@::@@:::::@::::::: :: : ::: :::::::@ ::::::: ::
     |   @               ::#:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::::@@:::::::::: #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
   0 +----------------------------------------------------------------------->Mi
     0                                                                   292.4

juntamente com informações de uso de memória excessivamente detalhadas. Detalhes no manual do valgrind .

Os programas serão executados cerca de 20x mais lentamente. Além disso, executei alguns comandos dentro do xterm. Sua pegada de memória foi levada em consideração porque --trace-children=yesa opção está lá!

Stéphane Gimenez
fonte
1
A penalidade de velocidade de 20x torna-o inadequado para a minha situação. Caso contrário, gráfico muito bonito!
precisa saber é o seguinte
1
Parece que, pelo menos na versão 3.8.1 do valgrind que estou usando, os booleanos são aceitos apenas no formato "yes / no" e não "true / false". O meu reclamou! :-)
MakisH 17/02
6

Embora o tópico seja bastante antigo, quero compartilhar outro projeto que surgiu a partir do recurso do kernel Linux do cgroups.

https://github.com/gsauthof/cgmemtime :

O cgmemtime mede o uso de memória RSS + CACHE de alto nível de um processo e seus processos descendentes.

Para poder fazer isso, coloca o processo em seu próprio cgroup.

Por exemplo, o processo A aloca 10 MiB e bifurca um filho B que aloca 20 MiB e que bifurca um filho C que aloca 30 MiB. Todos os três processos compartilham uma janela de tempo em que suas alocações resultam no uso correspondente da memória RSS (tamanho do conjunto residente).

A questão agora é: quanta memória é realmente usada como resultado da execução de A?

Resposta: 60 MiB

cgmemtime é a ferramenta para responder a essas perguntas.

Vlad Frolov
fonte
3

Parece que o tstime não funciona mais no sistema não-root no Linux> = 3.0. Aqui está um utilitário de pesquisa que escrevi para solucionar o problema: https://github.com/jhclark/memusg/blob/master/memusg

jhclark
fonte
/usr/bin/time -vfornece a saída correta nas versões mais recentes. Nas versões mais antigas, você só precisa dividir por 4 para obter a quantidade correta.
precisa saber é o seguinte
No entanto, não acho que o time -v suporte o tamanho máximo da memória (apenas RSS). Alguém pode confirmar isso na versão mais recente?
Jhclark #