Pico de uso da memória de um processo linux / unix


376

Existe uma ferramenta que execute uma linha de comando e relate o total de pico de uso de RAM?

Estou imaginando algo análogo a / usr / bin / time

Respostas:


28

Aqui está uma linha que não requer scripts ou utilitários externos e não requer que você inicie o processo por outro programa como o Valgrind ou o time, para que você possa usá-lo para qualquer processo que já esteja em execução:

grep VmPeak /proc/$PID/status

(substitua $PIDpelo PID do processo em que você está interessado)


4
E se eu não conhecer o PID? Por exemplo no caso de quando o programa é executado uma pequena quantidade de tempo (<1s)
diralik

4
"VmHWM: tamanho máximo do conjunto de residentes" pode ser mais útil para medir o uso da RAM (em vez do VmPeak, que inclui muitas outras coisas também).
jfs

@ jfs realmente depende do que você deseja descobrir. IIRC VmPeak é o uso máximo de memória total, incluindo memória virtual, enquanto VmHWM é o uso máximo de RAM. Portanto, se você quiser saber a quantidade total de memória solicitada pelo seu programa, use o VmPeak; se você quiser saber quanto de sua RAM real já usou em um determinado momento, use o VmHWM.
erobertc

11
@diralik se você estiver verificando um programa criado por você, poderá incorporar uma linha de código para procurar no arquivo "/ proc / self / status".
Fileland

404

[ Edit : Funciona no Ubuntu 14.04: /usr/bin/time -v command Certifique-se de usar o caminho completo.]

Parece /usr/bin/timeque você fornece essas informações, se você passar -v(isso é no Ubuntu 8.10). Veja, por exemplo, Maximum resident set sizeabaixo:

$ / usr / bin / time -v ls /
....
        Comando sendo cronometrado: "ls /"
        Tempo do usuário (segundos): 0.00
        Tempo do sistema (segundos): 0,01
        Porcentagem de CPU que este trabalho obteve: 250%
        Tempo decorrido (relógio de parede) (h: mm: ss ou m: ss): 0: 00.00
        Tamanho médio do texto compartilhado (kbytes): 0
        Tamanho médio dos dados não compartilhados (kbytes): 0
        Tamanho médio da pilha (kbytes): 0
        Tamanho total médio (kbytes): 0
        Tamanho máximo do conjunto de residentes (kbytes): 0
        Tamanho médio do conjunto de residentes (kbytes): 0
        Falhas na página principal (que requer E / S): 0
        Falhas de página secundárias (recuperando um quadro): 315
        Mudanças de contexto voluntárias: 2
        Opções de contexto involuntárias: 0
        Swaps: 0
        Entradas do sistema de arquivos: 0
        Saídas do sistema de arquivos: 0
        Mensagens de soquete enviadas: 0
        Mensagens de soquete recebidas: 0
        Sinais entregues: 0
        Tamanho da página (bytes): 4096
        Status de saída: 0

4
Provavelmente sempre retorna 0 porque ls não está fazendo muito. Tente um comando mais intensivo da CPU.
21711 Jon Ericson

17
Na página do manual: a maioria das informações mostradas pelo tempo é derivada da chamada do sistema wait3 (2). Os números são tão bons quanto os retornados por wait3 (2). Nos sistemas que não têm uma chamada em espera3 (2) que retorna informações de status, as vezes (2) a chamada do sistema é usada. No entanto, ele fornece muito menos informações do que wait3 (2); portanto, nesses sistemas, o tempo informa a maioria dos recursos como zero.
6249 lothar

79
"bash: -v: comando não encontrado" significa que o bash intercepta o tempo para usá-lo. /bin/time -vresolve isso.
Gcb

3
Valeria a pena fazer uma verificação rápida para garantir que a saída faça sentido. Tempo Gnu tem um bug onde ele irá informar 4x o uso de memória real: stackoverflow.com/questions/10035232/...
Ian

24
@skalee Experimente o time -lMacOS, produz resultados semelhantes.
Volker Stolz

96

(Esta é uma pergunta antiga já respondida .. mas apenas para constar :)

Fui inspirado pelo script de Yang e criei esta pequena ferramenta, chamada memusg . Simplesmente aumentei a taxa de amostragem para 0,1 para lidar com processos de vida muito curtos. Em vez de monitorar um único processo, eu o fiz medir a soma rss do grupo de processos. (Sim, eu escrevo muitos programas separados que funcionam juntos) Atualmente, ele funciona no Mac OS X e Linux. O uso tinha que ser semelhante ao de time:

memusg ls -alR /> / dev / null

Ele mostra apenas o pico no momento, mas estou interessado em pequenas extensões para gravar outras estatísticas (aproximadas).

É bom ter uma ferramenta tão simples para dar uma olhada antes de iniciar qualquer perfil sério.


11
tudo o que ainda usa PS e serve apenas para determinar a memória superior observada. memória superior não real. você sempre pode perder algo entre um intervalo e outro.
Gcb

6
Quais são as unidades para a saída do script memusg? Bytes? Kilobytes?
Daniel Standage

11
@ DanielStandage: provavelmente em Kilobytes. Ele simplesmente observa os valores mostrados em ps -o rss=que rss é o tamanho da memória real (conjunto de residentes) do processo (em unidades de 1024 bytes) na minha página de manual do BSD.
netj

3
@gcb Então, é isso que você obtém ao medir amostras.
Volker Stolz

2
O link para memusg fornecido na resposta parece estar quebrado. De qualquer forma, / usr / bin / time faz isso muito bem.
Tom Cornebize #

65

Linha única Valgrind:

valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1

Observe o uso de --pages-as-heap para medir toda a memória em um processo. Mais informações aqui: http://valgrind.org/docs/manual/ms-manual.html


14
time, Estou deixando você.
Jbeard4

11
Script acessível, mas eu preciso classificar -g no meu sistema Slackware (presumo que você esteja procurando o valor mais alto).
Nick Coleman

3
+1 para valgrind --massif. Você também pode usar a ms_printferramenta que vem com ele para a saída acessível (incluindo gráficos ascii de uso ao longo do tempo)
Eli Bendersky

7
O maciço possui uma sobrecarga muito maior do que o timenormal, levando pelo menos 10 vezes mais tempo em um comando como esse ls.
Timothy Gu

8
É realmente massivo demais. Esta resposta deve mencionar o abrandamento. O comando que quero medir normalmente leva 35 segundos para ser concluído. Eu corri este comando valgrind para medi-la mais de meia hora atrás, e ainda não foi concluída ...
unagi

35

No Linux:

Use /usr/bin/time -v <program> <args>e procure " Tamanho máximo do conjunto de residentes ".

(Não deve ser confundida com o Bash timecomando interno! Portanto, use o caminho completo , /usr/bin/time)

Por exemplo:

> /usr/bin/time -v ./myapp
        User time (seconds): 0.00
        . . .
        Maximum resident set size (kbytes): 2792
        . . .

No BSD, MacOS:

Use /usr/bin/time -l <program> <args>, procurando " tamanho máximo do conjunto de residentes ":

>/usr/bin/time -l ./myapp
        0.01 real         0.00 user         0.00 sys
      1440  maximum resident set size
      . . .

sudo apt-get install time
Rolf

2
Esse terreno já não está coberto por uma resposta adicionada dois anos antes ?
Charles Duffy

34

Talvez o (gnu) time (1) já faça o que você deseja. Por exemplo:

$ /usr/bin/time -f "%P %M" command
43% 821248

Mas outras ferramentas de criação de perfil podem fornecer resultados mais precisos, dependendo do que você está procurando.


I parecem sempre obter zeros com isso, mesmo para comandos grandes
jes5199

Eu recebo resultados variáveis, como 400% 0 e 0% 0 no mesmo programa .. talvez seja que deva ser executado por períodos maiores para ser exato?
Liran Orevi 21/04/09

Não sei o que sugerir. O código acima é exatamente o que eu obtive executando um comando de látex que estava no histórico. Como eu disse, resultados mais precisos podem ser obtidos com outras ferramentas.
21710 Jon Ericson

2
Isso funciona em pelo menos sistemas CentOS (e, portanto, aposto que também RHEL). % P fornece estatísticas não relacionadas (% de CPU) que dependem do agendador e, portanto, são bastante variáveis.
Blaisorblade 19/09/11

2
@ Deleteman: timeé um comando incorporado ao usar csh. Se você usar o caminho exato, ele permitirá que você execute o comando externo. Até onde eu sei, apenas a versão GNU suporta a opção de formato.
Jon Ericson

18

/ usr / bin / time talvez faça o que você quer, na verdade. Algo como.

 / usr / bin / time --format = '(% Xtext +% Ddata% Mmax)'

Veja o tempo (1) para detalhes ...


11
I parecem sempre obter zeros com isso, mesmo para comandos grandes
jes5199

jes5199, Liran, olhando para comentários acima parece tempo (1) pode ser quebrado para relatórios de memória em algumas Linuxes ...
simon

No Ubuntu 16.04, texto e dados são zero, mas max é diferente de zero e produz um valor significativo. Estou feliz com isso.
Stéphane Gourichon

Espero Mmax não significa que nós queremos que ele quer dizer .... a página do manual é um pouco concisa sobre isso
matanster

17

No MacOS Sierra, use:

/usr/bin/time -l commandToMeasure

Você pode usar greppara pegar o que quiser, talvez.


5
Este! Eu literalmente passei uma hora tentando obter o Instruments.app e o dtrace para me fornecer um perfil de memória com a integridade do sistema ativada (não é possível desativá-lo), enquanto tudo que eu precisava era apenas um simples comando. Uma pequena nota, você pode usar em command time -lvez do /usr/bin/time -lque fará com que o seu shell realmente chame um binário chamado em timevez da função interna. (Sim, commandnão é um espaço reservado, command timeé diferente do que apenas time.)
Jakub Arnold

16

Se o processo for executado por pelo menos alguns segundos, você poderá usar o seguinte script bash, que executará a linha de comando especificada e imprimirá o stderr do RSS de pico (substitua rssqualquer outro atributo no qual você esteja interessado). É um pouco leve e funciona para mim com o psincluído no Ubuntu 9.04 (o que não posso dizer time).

#!/usr/bin/env bash
"$@" & # Run the given command line in the background.
pid=$! peak=0
while true; do
  sleep 1
  sample="$(ps -o rss= $pid 2> /dev/null)" || break
  let peak='sample > peak ? sample : peak'
done
echo "Peak: $peak" 1>&2

11
A principal desvantagem desse método é que, se o processo alocar muita memória por um curto período (por exemplo, próximo ao final), isso poderá não ser detectado. Reduzir o tempo de sono pode ajudar um pouco.
vinc17


8

Bem, se você realmente deseja mostrar o pico de memória e algumas estatísticas mais detalhadas, recomendo usar um criador de perfil como o valgrind . Um bom front-end do valgrind é o alleyoop .



5

Aqui está (com base nas outras respostas) um script muito simples que assiste a um processo já em execução. Você acabou de executá-lo com o pid do processo que deseja assistir como argumento:

#!/usr/bin/env bash

pid=$1

while ps $pid >/dev/null
do
    ps -o vsz= ${pid}
    sleep 1
done | sort -n | tail -n1

Exemplo de uso:

max_mem_usage.sh 23423


1

Heaptrack é uma ferramenta do KDE que possui uma interface gráfica e de texto. Acho mais adequado do que o valgrind entender o uso da memória de um processo, pois fornece mais detalhes e gráficos. Também é mais rápido porque faz menos verificação desse valor. E fornece o pico de uso da memória.

De qualquer forma, rastrear rss e vss é enganoso porque as páginas podem ser compartilhadas, é por isso que memusg. O que você realmente deve fazer é acompanhar a soma de Pssin /proc/[pid]/smapsou use pmap. O monitor do sistema GNOME costumava fazer isso, mas era muito caro.


1

Re-inventando a roda, com script bash feito à mão. Rápido e limpo.

Meu caso de uso: eu queria monitorar uma máquina Linux com menos RAM e tirar uma foto instantânea do uso por contêiner quando executado sob uso pesado.

#!/usr/bin/env bash

threshold=$1

echo "$(date '+%Y-%m-%d %H:%M:%S'): Running free memory monitor with threshold $threshold%.."

while(true)
    freePercent=`free -m | grep Mem: | awk '{print ($7/$2)*100}'`    
  do

  if (( $(awk 'BEGIN {print ("'$freePercent'" < "'$threshold'")}') ))
  then
       echo "$(date '+%Y-%m-%d %H:%M:%S'): Free memory $freePercent% is less than $threshold%"
       free -m
       docker stats --no-stream
       sleep 60  
       echo ""  
  else
       echo "$(date '+%Y-%m-%d %H:%M:%S'): Sufficient free memory available: $freePercent%"
  fi
  sleep 30

done

Saída de amostra:

2017-10-12 13:29:33: Executando monitor de memória livre com limite de 30% ..

2017-10-12 13:29:33: Memória livre suficiente disponível: 69.4567%

2017-10-12 13:30:03: Memória livre suficiente disponível: 69.4567%

2017-10-12 16:47:02: Memória livre 18.9387% é inferior a 30%

sua Saída de Comando Customizada


1

No macOS, você pode usar o DTrace. O aplicativo "Instruments" é uma ótima interface gráfica para isso, vem com o XCode afaik.



-2

Certifique-se de responder à pergunta. Forneça detalhes e compartilhe sua pesquisa!

Desculpe, sou a primeira vez aqui e só posso fazer perguntas ...

Usado sugerido:

valgrind --tool=massif --pages-as-heap=yes --massif-out-file=massif.out ./test.sh; grep mem_heap_B massif.out | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1

então:

grep mem_heap_B massif.out
...
mem_heap_B=1150976
mem_heap_B=1150976
...

isso é muito diferente do que o topcomando mostra em um momento semelhante:

14673 gu27mox   20   0 3280404 468380  19176 R 100.0  2.9   6:08.84 pwanew_3pic_com

o que são unidades medidas do Valgrind?

O /usr/bin/time -v ./test.shnunca respondeu - você deve alimentar diretamente o executável para /usr/bin/timegostar:

/usr/bin/time -v  pwanew_3pic_compass_2008florian3_dfunc.static  card_0.100-0.141_31212_resubmit1.dat_1.140_1.180   1.140 1.180 31212


    Command being timed: "pwanew_3pic_compass_2008florian3_dfunc.static card_0.100-0.141_31212_resubmit1.dat_1.140_1.180 1.140 1.180 31212"

    User time (seconds): 1468.44
    System time (seconds): 7.37
    Percent of CPU this job got: 99%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 24:37.14
    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): 574844
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 74
    Minor (reclaiming a frame) page faults: 468880
    Voluntary context switches: 1190
    Involuntary context switches: 20534
    Swaps: 0
    File system inputs: 81128
    File system outputs: 1264
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.