Utilisation maximale de la mémoire d'un processus Linux / Unix


376

Existe-t-il un outil qui exécutera une ligne de commande et indiquera le total d'utilisation maximale de la RAM?

J'imagine quelque chose d'analogue à / usr / bin / time

Réponses:


28

Voici une ligne qui ne nécessite aucun script ou utilitaire externe et ne vous oblige pas à démarrer le processus via un autre programme comme Valgrind ou time, vous pouvez donc l'utiliser pour n'importe quel processus déjà en cours d'exécution:

grep VmPeak /proc/$PID/status

(remplacez $PIDpar le PID du processus qui vous intéresse)


4
Et si je ne connais pas le PID? Par exemple dans le cas où le programme s'exécute un peu de temps (<1 s)
diralik

4
"VmHWM: Peak set set size" pourrait être plus utilisable pour mesurer l'utilisation de la RAM (au lieu de VmPeak qui inclut aussi beaucoup d'autres choses).
jfs

@jfs cela dépend vraiment de ce que vous voulez savoir. IIRC VmPeak est l'utilisation maximale totale de la mémoire, y compris la mémoire virtuelle, tandis que VmHWM est l'utilisation maximale de la RAM. Donc, si vous voulez connaître la quantité totale de mémoire demandée par votre programme, utilisez VmPeak; si vous voulez savoir combien de votre RAM réelle il a déjà utilisée à un moment donné, utilisez VmHWM.
erobertc

1
@diralik si vous vérifiez un programme écrit par vous-même, vous pouvez incorporer une ligne de code pour regarder dans le fichier "/ proc / self / status".
Fileland

405

[ Edit : Works on Ubuntu 14.04: /usr/bin/time -v command Assurez-vous d'utiliser le chemin complet.]

On dirait que /usr/bin/timecela vous donne ces informations, si vous réussissez -v(c'est sur Ubuntu 8.10). Voir, par exemple, Maximum resident set sizeci - dessous:

$ / usr / bin / time -v ls /
....
        La commande est chronométrée: "ls /"
        Temps utilisateur (secondes): 0,00
        Temps système (secondes): 0,01
        Pourcentage de CPU obtenu pour ce travail: 250%
        Temps écoulé (horloge murale) (h: mm: ss ou m: ss): 0: 00.00
        Taille moyenne du texte partagé (kilo-octets): 0
        Taille moyenne des données non partagées (kilo-octets): 0
        Taille moyenne de la pile (kilo-octets): 0
        Taille totale moyenne (kilo-octets): 0
        Taille maximale de l'ensemble résident (kilo-octets): 0
        Taille moyenne de l'ensemble résident (kilo-octets): 0
        Défauts de page majeurs (nécessitant des E / S): 0
        Erreurs de page mineures (récupération d'un cadre): 315
        Changements de contexte volontaires: 2
        Changements de contexte involontaires: 0
        Échanges: 0
        Entrées du système de fichiers: 0
        Sorties du système de fichiers: 0
        Messages de socket envoyés: 0
        Messages de socket reçus: 0
        Signaux délivrés: 0
        Taille de la page (octets): 4096
        Statut de sortie: 0

4
Il renvoie probablement toujours 0 car ls ne fait pas grand-chose. Essayez une commande plus gourmande en CPU.
Jon Ericson

17
Depuis la page de manuel: La plupart des informations affichées par l'heure proviennent de l'appel système wait3 (2). Les chiffres sont aussi bons que ceux renvoyés par wait3 (2). Sur les systèmes qui n'ont pas d'appel wait3 (2) qui renvoie des informations d'état, l'appel système times (2) est utilisé à la place. Cependant, il fournit beaucoup moins d'informations que wait3 (2), donc sur ces systèmes, le temps signale la majorité des ressources comme étant nulles.
lothar

79
"bash: -v: commande introuvable" signifie que bash intercepte le temps pour utiliser le sien. /bin/time -vle résout.
gcb

3
Il vaudrait la peine de faire une vérification rapide pour être sûr que la sortie a du sens. Le temps Gnu a un bug où il rapportera 4x l'utilisation réelle de la mémoire: stackoverflow.com/questions/10035232/…
Ian

24
@skalee Try time -lsur MacOS, donne une sortie similaire.
Volker Stolz

96

(C'est une vieille question déjà répondue .. mais juste pour mémoire :)

J'ai été inspiré par le script de Yang et j'ai trouvé ce petit outil, nommé memusg . J'ai simplement augmenté le taux d'échantillonnage à 0,1 pour gérer les processus de vie très courts. Au lieu de surveiller un seul processus, je l'ai fait mesurer la somme rss du groupe de processus. (Oui, j'écris beaucoup de programmes distincts qui fonctionnent ensemble) Il fonctionne actuellement sur Mac OS X et Linux. L'usage devait être similaire à celui de time:

memusg ls -alR /> / dev / null

Cela ne montre que le pic pour le moment, mais je suis intéressé par de légères extensions pour enregistrer d'autres statistiques (approximatives).

Il est bon d'avoir un outil aussi simple pour jeter un œil avant de commencer un profilage sérieux.


1
tout ce qui utilise toujours PS et ne sert qu'à déterminer la mémoire supérieure observée. pas une vraie mémoire. vous pouvez toujours manquer quelque chose entre un intervalle et un autre.
gcb

6
Quelles sont les unités de sortie du script memusg? Octets? Kilo-octets?
Daniel Standage

1
@DanielStandage: probablement en kilo-octets. Il regarde simplement les valeurs indiquées par ps -o rss=où rss est la taille réelle de la mémoire (ensemble résident) du processus (en unités de 1024 octets) à partir de ma page de manuel BSD.
netj

3
@gcb Alors quoi, c'est ce que vous obtenez lorsque vous mesurez des échantillons.
Volker Stolz

2
Le lien vers memusg donné dans la réponse semble rompu. Quoi qu'il en soit, / usr / bin / time le fait très bien.
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

Notez l'utilisation de --pages-as-heap pour mesurer toute la mémoire d'un processus. Plus d'informations ici: http://valgrind.org/docs/manual/ms-manual.html


14
time, Je te quitte.
jbeard4

1
Script pratique, mais j'ai besoin de trier -g sur mon système Slackware (je suppose que vous recherchez la valeur la plus élevée).
Nick Coleman

3
+1 pour valgrind --massif. Vous pouvez également utiliser l' ms_printoutil qui l'accompagne pour une sortie pratique (y compris des graphiques d'utilisation ascii au fil du temps)
Eli Bendersky

7
Massif a un temps système beaucoup plus élevé que timecela, prenant au moins 10 fois plus de temps sur une commande comme ls.
Timothy Gu,

8
C'est beaucoup trop massif en effet. Cette réponse devrait mentionner le ralentissement. La commande que je veux mesurer prend normalement 35 secondes. J'ai exécuté cette commande valgrind pour la mesurer il y a plus d'une demi-heure, et elle n'est toujours pas terminée…
unagi

35

Sous Linux:

Utilisez /usr/bin/time -v <program> <args>et recherchez « Taille maximale du jeu de résidents ».

(À ne pas confondre avec la timecommande intégrée Bash ! Utilisez donc le chemin complet , /usr/bin/time)

Par exemple:

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

Sur BSD, MacOS:

Utilisation /usr/bin/time -l <program> <args>, à la recherche de " taille maximale de l'ensemble de résidents ":

>/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
Ce motif n'est-il pas déjà couvert par une réponse ajoutée deux ans auparavant ?
Charles Duffy

34

Peut-être que (gnu) time (1) fait déjà ce que vous voulez. Par exemple:

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

Mais d'autres outils de profilage peuvent donner des résultats plus précis en fonction de ce que vous recherchez.


Il semble que j'obtienne toujours des zéros avec cela, même pour les grosses commandes
jes5199

J'obtiens des résultats variables, comme 400% 0 et 0% 0 sur le même programme. Peut-être devrait-il être exécuté pendant de plus longues périodes pour être exact?
Liran Orevi

Je ne sais pas quoi suggérer. Le code ci-dessus est exactement ce que j'ai obtenu en exécutant une commande latex qui se trouvait dans l'histoire. Comme je l'ai dit, des résultats plus précis peuvent être obtenus avec d'autres outils.
Jon Ericson

2
Cela fonctionne sur au moins les systèmes CentOS (et donc, je parie, aussi RHEL). % P donne des statistiques indépendantes (% CPU) qui dépendent du planificateur et sont donc assez variables.
Blaisorblade

2
@Deleteman: timeest une commande intégrée lors de l'utilisation csh. Si vous utilisez le chemin exact, il vous permettra d'exécuter la commande externe. Pour autant que je sache, seule la version GNU prend en charge l'option de format.
Jon Ericson

18

/ usr / bin / time fait peut-être ce que vous voulez, en fait. Quelque chose comme.

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

Voir l'heure (1) pour plus de détails ...


1
Il semble que j'obtienne toujours des zéros avec cela, même pour les grosses commandes
jes5199

jes5199, Liran, en regardant les commentaires ci-dessus, il semble que le temps (1) puisse être cassé pour les rapports de mémoire sur certains linux ...
simon

Sur Ubuntu 16.04, le texte et les données sont nuls, mais max est différent de zéro et produit une valeur significative. J'en suis content.
Stéphane Gourichon

J'espère que Mmax signifie ce que nous voulons que cela signifie ... la page de manuel est un peu laconique à ce sujet
matanster

17

Sur MacOS Sierra, utilisez:

/usr/bin/time -l commandToMeasure

Vous pouvez utiliser greppour prendre ce que vous voulez peut-être.


5
Cette! J'ai littéralement passé une heure à essayer d'obtenir Instruments.app et dtrace pour me donner un profil de mémoire avec l'intégrité du système activée (ne peut pas le désactiver), alors que tout ce dont j'avais besoin était juste cette simple commande. Une petite note que vous pouvez utiliser à la command time -lplace de /usr/bin/time -llaquelle votre shell appellera en fait un binaire appelé à la timeplace de la fonction intégrée. (Oui, ce commandn'est pas un espace réservé, command timec'est différent de juste time.)
Jakub Arnold

16

Si le processus s'exécute pendant au moins quelques secondes, vous pouvez utiliser le script bash suivant, qui exécutera la ligne de commande donnée, puis imprimera pour stderr le pic RSS (remplacez rsstout autre attribut qui vous intéresse). Il est un peu léger et il fonctionne pour moi avec le psinclus dans Ubuntu 9.04 (que je ne peux pas dire pour 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
L'inconvénient majeur de cette méthode est que si le processus alloue beaucoup de mémoire pendant une courte période (par exemple vers la fin), cela peut ne pas être détecté. Réduire le temps de sommeil peut aider un peu.
vinc17


8

Eh bien, si vous voulez vraiment montrer le pic de mémoire et quelques statistiques plus approfondies, je recommande d'utiliser un profileur tel que valgrind . Un bon front-end valgrind est alleyoop .



5

Voici (basé sur les autres réponses) un script très simple qui surveille un processus déjà en cours. Vous venez de l'exécuter avec le pid du processus que vous souhaitez regarder comme argument:

#!/usr/bin/env bash

pid=$1

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

Exemple d'utilisation:

max_mem_usage.sh 23423


1

Heaptrack est un outil KDE qui possède une interface graphique et une interface texte. Je trouve plus approprié que valgrind de comprendre l'utilisation de la mémoire d'un processus car il fournit plus de détails et de graphiques de flamme. C'est aussi plus rapide car il vérifie moins ce valgrind. Et cela vous donne l'utilisation maximale de la mémoire.

Quoi qu'il en soit, le suivi des rss et des vss est trompeur car les pages peuvent être partagées, c'est pourquoi cela memusg. Ce que vous devez vraiment faire est de suivre la somme Pssdans /proc/[pid]/smapsou à l' utilisation pmap. Le moniteur système GNOME le faisait auparavant mais c'était trop cher.


1

Réinventer la roue, avec un script bash fait à la main. Rapide et propre.

Mon cas d'utilisation: je voulais surveiller une machine Linux qui a moins de RAM et je voulais prendre un instantané de l'utilisation par conteneur lorsqu'elle fonctionne sous une utilisation intensive.

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

Exemple de sortie:

12-10-2017 13:29:33: Exécution d'un moniteur de mémoire libre avec un seuil de 30%.

2017-10-12 13:29:33: Mémoire disponible suffisante: 69.4567%

2017-10-12 13:30:03: Mémoire disponible suffisante: 69.4567%

2017-10-12 16:47:02: La mémoire libre de 18,9387% est inférieure à 30%

votre sortie de commande personnalisée


1

Sur macOS, vous pouvez utiliser DTrace à la place. L'application "Instruments" est une belle interface graphique pour cela, elle est livrée avec XCode afaik.



-2

Assurez-vous de répondre à la question. Donnez des détails et partagez vos recherches!

Désolé, je suis la première fois ici et je ne peux que poser des questions…

Utilisé suggéré:

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

puis:

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

c'est très différent de ce que la topcommande montre au même moment:

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

quelles sont les unités mesurées de Valgrind ??

Le /usr/bin/time -v ./test.shjamais répondu - vous devez directement nourrir l'exécutable pour /usr/bin/timeaimer:

/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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.