Utilizzo massimo della memoria di un processo linux / unix


376

Esiste uno strumento che eseguirà una riga di comando e segnalerà il picco di utilizzo totale della RAM?

Sto immaginando qualcosa di analogo a / usr / bin / time

Risposte:


28

Ecco un one-liner che non richiede alcuno script esterno o utility e non ti richiede di avviare il processo tramite un altro programma come Valgrind o time, quindi puoi usarlo per qualsiasi processo che è già in esecuzione:

grep VmPeak /proc/$PID/status

(sostituisci $PIDcon il PID del processo che ti interessa)


4
Cosa succede se non conosco il PID? Ad esempio nel caso in cui il programma esegua una piccola quantità di tempo (<1s)
diralik

4
"VmHWM: Peak set resident set size" potrebbe essere più utilizzabile per misurare l'utilizzo della RAM (invece di VmPeak che include molte altre cose).
jfs,

@jfs dipende davvero da cosa vuoi scoprire. IIRC VmPeak è l'utilizzo di memoria totale massimo compresa la memoria virtuale, mentre VmHWM è l'utilizzo massimo di RAM. Quindi, se vuoi conoscere la quantità totale di memoria richiesta dal tuo programma, usa VmPeak; se vuoi sapere quanta RAM effettiva ha mai usato in un dato momento, usa VmHWM.
Erobertc,

1
@diralik se stai controllando un programma scritto da te, puoi incorporare una riga di codice per guardare nel file "/ proc / self / status".
Fileland

405

[ Modifica : funziona su Ubuntu 14.04: /usr/bin/time -v command assicurati di utilizzare il percorso completo.]

Sembra /usr/bin/timeche ti dia queste informazioni, se passi -v(questo è su Ubuntu 8.10). Vedi, ad esempio, di Maximum resident set sizeseguito:

$ / usr / bin / time -v ls /
....
        Comando temporizzato: "ls /"
        Tempo utente (secondi): 0.00
        Tempo di sistema (secondi): 0.01
        Percentuale di CPU ottenute da questo lavoro: 250%
        Tempo trascorso (orologio da parete) (h: mm: ss o m: ss): 0: 00.00
        Dimensione media del testo condiviso (kbyte): 0
        Dimensione media dei dati non condivisi (kbyte): 0
        Dimensione media dello stack (kbyte): 0
        Dimensione totale media (kbyte): 0
        Dimensione massima impostata per residenti (kbyte): 0
        Dimensione media residente impostata (kbyte): 0
        Errori di pagina principali (che richiedono I / O): 0
        Errori di pagina minori (recupero di una cornice): 315
        Interruttori di contesto volontari: 2
        Interruttori di contesto involontari: 0
        Swap: 0
        Input del file system: 0
        Output del file system: 0
        Messaggi socket inviati: 0
        Messaggi socket ricevuti: 0
        Segnali consegnati: 0
        Dimensione della pagina (byte): 4096
        Stato uscita: 0

4
Probabilmente restituisce sempre 0 perché ls non sta facendo molto. Prova un comando più intensivo della CPU.
Jon Ericson,

17
Dalla pagina man: la maggior parte delle informazioni mostrate dal tempo derivano dalla chiamata di sistema wait3 (2). I numeri sono buoni solo come quelli restituiti da wait3 (2). Sui sistemi che non dispongono di una chiamata wait3 (2) che restituisce informazioni sullo stato, viene invece utilizzata la chiamata di sistema times (2). Tuttavia, fornisce molte meno informazioni di wait3 (2), quindi su quei sistemi il tempo riporta la maggior parte delle risorse come zero.
lothar,

79
"bash: -v: comando non trovato" significa che bash intercetta il tempo di usare il proprio. /bin/time -vlo risolve.
CG

3
Ne varrebbe la pena fare un rapido controllo per assicurarsi che l'output abbia un senso. Gnu time ha un bug in cui segnalerà 4x l'uso effettivo della memoria: stackoverflow.com/questions/10035232/…
Ian

24
@skalee Prova time -lsu MacOS, fornisce un output simile.
Volker Stolz,

96

(Questa è una vecchia domanda già risposta .. ma solo per la cronaca :)

Sono stato ispirato dalla sceneggiatura di Yang e ho ideato questo piccolo strumento, chiamato memusg . Ho semplicemente aumentato la frequenza di campionamento a 0,1 per gestire processi di vita molto brevi. Invece di monitorare un singolo processo, l'ho fatto misurare la somma rss del gruppo di processi. (Sì, scrivo molti programmi separati che lavorano insieme) Attualmente funziona su Mac OS X e Linux. L'utilizzo doveva essere simile a quello di time:

memusg ls -alR /> / dev / null

Mostra solo il picco per il momento, ma sono interessato a leggere estensioni per la registrazione di altre statistiche (approssimative).

È bello avere uno strumento così semplice per dare un'occhiata prima di iniziare una profilazione seria.


1
tutto ciò che utilizza ancora PS e sono buoni solo per determinare la memoria superiore osservata. memoria reale non reale. puoi sempre perdere qualcosa tra un intervallo e l'altro.
gcb,

6
Quali sono le unità per l'output dello script memusg? Bytes? Kilobyte?
Daniel Standage,

1
@DanielStandage: probabilmente in Kilobyte. Osserva semplicemente i valori mostrati da ps -o rss=dove rss è la dimensione della memoria reale (resident set) del processo (in unità da 1024 byte) dalla mia pagina man BSD.
netj

3
@gcb Quindi, ecco cosa ottieni misurando i campioni.
Volker Stolz,

2
Il collegamento a memusg fornito nella risposta sembra essere rotto. Comunque, / usr / bin / time lo fa molto bene.
Tom Cornebize,

65

Valgrind one-liner:

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

Nota l'uso di --pages-as-heap per misurare tutta la memoria in un processo. Maggiori informazioni qui: http://valgrind.org/docs/manual/ms-manual.html


14
time, Ti sto lasciando.
jbeard4,

1
Script pratico, ma ho bisogno di ordinare -g sul mio sistema Slackware (presumo che tu stia cercando il valore più alto).
Nick Coleman,

3
+1 per valgrind --massif. È inoltre possibile utilizzare lo ms_printstrumento fornito per un output utile (inclusi i grafici di utilizzo ASCII nel tempo)
Eli Bendersky

7
Il massiccio ha un overhead molto più elevato di timequanto non lo sia, impiegando almeno 10 volte più tempo con un comando simile ls.
Timothy Gu,

8
È davvero troppo massiccio. Questa risposta dovrebbe menzionare il rallentamento. Il comando che voglio misurare normalmente richiede 35 secondi per essere completato. Ho eseguito questo comando valgrind per misurarlo più di mezz'ora fa, e non è stato ancora completato ...
unagi

35

Su Linux:

Utilizzare /usr/bin/time -v <program> <args>e cercare " Dimensione massima impostata per residenti ".

(Da non confondere con il timecomando integrato di Bash ! Quindi usa il percorso completo , /usr/bin/time)

Per esempio:

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

Su BSD, MacOS:

Utilizzare /usr/bin/time -l <program> <args>, cercando " dimensione massima impostata per residenti ":

>/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
Questo argomento non è già coperto da una risposta aggiunta due anni prima ?
Charles Duffy,

34

Forse (gnu) time (1) fa già quello che vuoi. Per esempio:

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

Ma altri strumenti di profilazione possono fornire risultati più accurati a seconda di ciò che stai cercando.


Mi sembra di ottenere sempre zeri con questo, anche per comandi di grandi dimensioni
jes5199

Ottengo risultati variabili, come 400% 0 e 0% 0 sullo stesso programma. Forse è necessario eseguirlo per periodi di tempo più lunghi per l'esattezza?
Liran Orevi,

Non so cosa suggerire. Il codice sopra è esattamente quello che ho ottenuto eseguendo un comando in lattice che è successo nella storia. Come ho detto, risultati più accurati possono essere ottenuti con altri strumenti.
Jon Ericson,

2
Funziona su almeno i sistemi CentOS (e quindi, scommetto, anche RHEL). % P fornisce statistiche non correlate (% CPU) che dipendono dallo scheduler ed è quindi abbastanza variabile.
Blaisorblade,

2
@Deleteman: timeè un comando integrato durante l'utilizzo csh. Se si utilizza il percorso esatto, sarà possibile eseguire il comando esterno. Per quanto ne so, solo la versione GNU supporta l'opzione di formattazione.
Jon Ericson,

18

/ usr / bin / time forse fa quello che vuoi, in realtà. Qualcosa di simile a.

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

Vedi tempo (1) per i dettagli ...


1
Mi sembra di ottenere sempre zeri con questo, anche per comandi di grandi dimensioni
jes5199

jes5199, Liran, guardando i commenti sopra sembra che il tempo (1) possa essere rotto per la segnalazione della memoria su alcuni Linux ...
simon

Su Ubuntu 16.04, testo e dati sono zero, ma max è diverso da zero e produce un valore significativo. Ne sono contento.
Stéphane Gourichon,

Spero che Mmax significhi quello che vogliamo che significhi ... la pagina man è un po '
concisa al

17

Su MacOS Sierra utilizzare:

/usr/bin/time -l commandToMeasure

Puoi usare grepper prendere quello che vuoi forse.


5
Questo! Ho letteralmente passato un'ora a cercare di ottenere Instruments.app e dtrace per darmi un profilo di memoria con l'integrità del sistema attivata (impossibile disattivarla), mentre tutto ciò di cui avevo bisogno era solo questo semplice comando. Una piccola nota, che puoi usare al command time -lposto della /usr/bin/time -lquale farà sì che la tua shell chiami effettivamente un binario chiamato timeinvece della funzione builtin. (Sì, commandnon è un segnaposto, command timeè diverso dal solo time.)
Jakub Arnold,

16

Se il processo viene eseguito per almeno un paio di secondi, è possibile utilizzare il seguente script bash, che eseguirà la riga di comando indicata, quindi stampa su stderr il picco RSS (in sostituzione di rssqualsiasi altro attributo che ti interessa). È in qualche modo leggero e funziona per me con psincluso in Ubuntu 9.04 (che non posso dire per 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

1
Il principale svantaggio di questo metodo è che se il processo alloca molta memoria per un breve periodo (ad esempio vicino alla fine), questo potrebbe non essere rilevato. Ridurre il tempo di sonno può aiutare un po '.
vinc17,


8

Bene, se vuoi davvero mostrare il picco di memoria e alcune statistiche più approfondite, ti consiglio di usare un profiler come valgrind . Un bel front-end valgrind è alleyoop .



5

Ecco (in base alle altre risposte) uno script molto semplice che osserva un processo già in esecuzione. Lo esegui semplicemente con il pid del processo che vuoi guardare come argomento:

#!/usr/bin/env bash

pid=$1

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

Esempio di utilizzo:

max_mem_usage.sh 23423


1

Heaptrack è lo strumento di KDE che ha una GUI e un'interfaccia di testo. Trovo più adatto di valgrind capire l'uso della memoria di un processo perché fornisce maggiori dettagli e flamegraph. È anche più veloce perché controlla meno quel valgrind. E ti dà il massimo utilizzo della memoria.

Ad ogni modo, il monitoraggio di rss e vss è fuorviante perché le pagine potrebbero essere condivise, ecco perché memusg. Quello che dovresti davvero fare è monitorare la somma di Pssin /proc/[pid]/smapso use pmap. Il monitor di sistema GNOME era solito farlo, ma era troppo costoso.


1

Reinventare la ruota, con script bash fatti a mano. Veloce e pulito.

Il mio caso d'uso: volevo monitorare una macchina linux che ha meno RAM e volevo fare un'istantanea dell'utilizzo per container quando viene eseguita in condizioni di utilizzo intenso.

#!/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

Uscita campione:

12-10-2017 13:29:33: Esecuzione di monitor di memoria libera con soglia del 30% ..

12-10-2017 13:29:33: memoria disponibile sufficiente: 69.4567%

12-10-2017 13:30:03: memoria disponibile sufficiente: 69.4567%

12-10-2017 16:47:02: memoria libera 18.9387% è inferiore al 30%

l'output del comando personalizzato


1

Su macOS, puoi invece usare DTrace. L'app "Instruments" è una bella GUI per questo, viene fornita con XCode afaik.



-2

Assicurati di rispondere alla domanda. Fornisci dettagli e condividi le tue ricerche!

Scusa, sono la prima volta qui e posso solo fare domande ...

Usato suggerito:

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

poi:

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

questo è molto diverso da quello che topmostra il comando in un momento simile:

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

quali sono le unità misurate da Valgrind ??

Il /usr/bin/time -v ./test.shmai risposto: devi alimentare direttamente l'eseguibile per /usr/bin/timepiacere:

/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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.