Mesurer l'utilisation de la RAM d'un programme

46

time est une commande brillante si vous voulez savoir combien de temps prend une commande donnée.

Je cherche quelque chose de similaire qui puisse mesurer l'utilisation maximale de RAM du programme et des enfants. De préférence, il convient de distinguer entre la mémoire allouée qui a été utilisée et non utilisée. Peut-être pourrait-il même donner l’utilisation médiane de la mémoire (c’est-à-dire l’utilisation de la mémoire à laquelle vous devriez vous attendre lorsqu’il est exécuté longtemps).

Donc j'aimerais faire:

rammeassure my_program my_args

et obtenir une sortie similaire à:

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

J'ai regardé memusg https://gist.github.com/526585/590293d6527c91e48fcb08db8de9fd6c88a6d82 mais je considère que c'est un peu un bidouillage.

Ole Tange
la source

Réponses:

24

Vous pouvez utiliser tstime pour mesurer l'utilisation de la mémoire vive (RSS et virtuelle) d'un processus.

Par exemple:

$ 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

Il prend également en charge un mode de sortie plus facile à analyser ( -t).

maxschlepzig
la source
Je l'aime. Il a même fait la bonne chose avec./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
Ole Tange
3
"L'utilisation de la RAM par le processus" n'est pas une valeur bien définie: s'il y a plusieurs instances du même programme en cours d'exécution, elles partagent le fichier exécutable. La plupart des programmes partagent glibc(et d'autres bibliothèques assorties, ils sont appelés "partagés" pour quelque chose). De nombreux démons chargent la configuration dans la mémoire et les enfants fork (2), qui partagent ensuite les données de configuration. Ensuite, il y a des données dans les tampons readahead / writebehind gérés par le noyau. Et puis, il existe des services qui constituent un ensemble de processus faiblement couplés (pensez à votre environnement de bureau et à ses applets et éléments d'arrière-plan).
vonbrand
@vonbrand, la manière dont le noyau Linux calcule les valeurs RSS / VSS est bien définie.
maxschlepzig
@maxschlepzig, il est possible que certaines valeurs aléatoires soient calculées, cela ne signifie pas qu'elles signifient ce que vous pensez qu'elles veulent dire: l'ensemble résident est constitué uniquement des pages de l'espace adresse du processus qui sont actuellement en mémoire. Ce n'est pas la "mémoire utilisée par ce processus", elle inclut tout ce qu'elle partage.
vonbrand
@vonbrand La plupart des cas d'utilisation de la mesure de la mémoire d'un processus consomment des pages anonymes non partagées, ce qui devrait être très prévisible avec la même entrée.
Vladimir Panteleev
28

timeest intégré à votre shell. Si vous aimez timemais avez besoin de plus d’informations, essayez GNU timeen -vmode verbose ( ):

/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

Recherchez le paquet "time" ou "gnutime" dans votre gestionnaire de paquets.

Rufo El Magufo
la source
3
Notez que certaines informations rapportées par l'heure GNU pourraient être inexactes. Par exemple, sous Ubuntu 10.04: La page de manuel indique 'Les nombres ne sont aussi bons que ceux renvoyés par wait3 (2)'. Cela wait3remplit une structure décrite dans getrusage(2): 'Tous les champs n'ont pas de sens sous Linux. [..] '.
maxschlepzig
4
Par exemple, sur un programme de test qui alloue exactement 10 Mo (et touche chaque page) - l'heure GNU indique un maximum de RSR de 42608 Ko - et de tstime10652 Ko. Encore une fois sous Ubuntu 10.04.
maxschlepzig
J'aurais aimé si c'était aussi simple. Sur ma machine Ubuntu j'ai essayé: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. top dit qu'il faut environ 570 Mo, mais le temps dit 2,3 Go. En pratique, ce nombre ne m’est pas utile.
Ole Tange
Le facteur de 4 est fixé dans le temps GNU 1.7 et fonctionne donc comme prévu.
Ole Tange
Remarque importante: la "Taille maximale du groupe de résidents" ne fonctionne que depuis Linux 2.6.32.
Jan Hudec
17

Peut-être exagéré, mais je viens de trouver que cet valgrindoutil est nommé massif. Je l'ai testé sur xterm:

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

Et vous obtenez un graphique d'utilisation de la mémoire agréable:

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

avec des informations d'utilisation de la mémoire trop détaillées. Détails dans le manuel valgrind .

Les programmes fonctionneront environ 20 fois plus lentement. Aussi, j'ai couru quelques commandes à l'intérieur du xterm. Leur empreinte mémoire a été prise en compte car --trace-children=yesl’option est là!

Stéphane Gimenez
la source
1
La pénalité de vitesse 20x la rend insoutenable pour ma situation. Sinon très joli graphique!
Ole Tange
1
On dirait que, du moins dans la version 3.8.1 de valgrind que j’utilise, les booléens ne sont acceptés que sous la forme "oui / non" et non "vrai / faux". Le mien s'est plaint! :-)
MakisH
6

Même si le sujet est assez ancien, je souhaite partager un autre projet issu de la fonctionnalité du noyau Linux de cgroups.

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

cgmemtime mesure l'utilisation de la mémoire en haute mer RSS + CACHE d'un processus et de ses processus descendants.

Pour ce faire, il met le processus dans son propre groupe de contrôle.

Par exemple, le processus A alloue 10 Mio et fourche un enfant B qui alloue 20 Mio et qui fourche un enfant C qui alloue 30 Mio. Les trois processus partagent une fenêtre temporelle dans laquelle leurs allocations entraînent une utilisation correspondante de la mémoire RSS (taille de l'ensemble résident).

La question qui se pose maintenant est la suivante: combien de mémoire est réellement utilisée à la suite de l’exécution de A?

Réponse: 60 MiB

cgmemtime est l'outil pour répondre à de telles questions.

Vlad Frolov
la source
3

On dirait que tstime ne fonctionne plus sous non-root sous Linux> = 3.0. Voici un utilitaire d'interrogation que j'ai écrit pour pirater le problème: https://github.com/jhclark/memusg/blob/master/memusg

jhclark
la source
/usr/bin/time -vdonne la sortie correcte dans les nouvelles versions. Dans les versions plus anciennes, il suffit de diviser par 4 pour obtenir le montant correct.
Ole Tange
Cependant, je ne pense pas que time -v supporte la taille maximale vmemory (uniquement RSS). Quelqu'un peut-il confirmer cela sur la dernière version?
Jhclark