Medir el uso de RAM de un programa

46

time es un comando brillante si desea calcular cuánto tiempo de CPU tarda un comando determinado.

Estoy buscando algo similar que pueda medir el uso máximo de RAM del programa y de cualquier niño. Preferiblemente debe distinguir entre la memoria asignada que se usó y la que no se usó. Tal vez incluso podría proporcionar el uso medio de memoria (por lo que el uso de memoria que debe esperar cuando se ejecuta durante mucho tiempo).

Entonces me gustaría hacer:

rammeassure my_program my_args

y obtener una salida similar a:

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

He visto memusg https://gist.github.com/526585/590293d6527c91e48fcb08edb8de9fd6c88a6d82 pero considero que esto es un truco.

Ole Tange
fuente

Respuestas:

24

Puede usar tstime para medir el uso de memoria de aguas altas (RSS y virtual) de un proceso.

Por ejemplo:

$ 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

También admite un modo de salida más fácil de analizar ( -t).

maxschlepzig
fuente
Me gusta. Incluso hizo lo correcto con./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
Ole Tange
3
El "uso de RAM por el proceso" no es un valor bien definido: si hay varias instancias del mismo programa ejecutándose, comparten el ejecutable. La mayoría de los programas comparten glibc(y otras bibliotecas variadas, se denominan "compartidas" por algo). Muchos demonios cargan la configuración en la memoria y los niños fork (2), que luego comparten los datos de configuración. Luego hay datos en buffers readahead / writebehind administrados por el kernel. Y luego están los servicios que son una manada de procesos débilmente acoplados (piense en su entorno de escritorio y todas sus aplicaciones y material de fondo).
vonbrand
@vonbrand, cómo el Linux-Kernel calcula los valores RSS / VSS está bien definido.
maxschlepzig
@maxschlepzig, bien puede calcular algunos valores aleatorios, eso no significa que signifiquen lo que crees que significan: el conjunto residente son solo las páginas en el espacio de direcciones del proceso que están actualmente en la memoria. Esa no es la "memoria utilizada por este proceso", incluye lo que está compartiendo.
vonbrand
@vonbrand La mayoría de los casos de uso de medición del uso de memoria de un proceso querrán medir páginas anónimas no compartidas, lo que debería ser muy predecible con la misma entrada.
Vladimir Panteleev
28

timeestá integrado en su shell. Si te gusta timepero necesitas más información, prueba GNU timeen modo detallado ( -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

Busque el paquete "time" o "gnutime" en su administrador de paquetes.

Rufo El Magufo
fuente
3
Tenga en cuenta que cierta información informada por el tiempo de GNU podría ser inexacta. Por ejemplo, en Ubuntu 10.04: la página del manual dice 'Los números son tan buenos como los que devuelve wait3 (2)'. Es decir, wait3llena una estructura que se describe en getrusage(2): 'No todos los campos son significativos en Linux. [..] '.
maxschlepzig
44
Por ejemplo, en un programa de prueba que asigna exactamente 10 MB (y toca cada página), el tiempo de GNU informa un valor máximo de 42608 KiB y tstime10652 KiB. De nuevo bajo Ubuntu 10.04.
maxschlepzig
Me hubiera encantado si fuera así de simple. En mi máquina Ubuntu Traté: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. arriba dice que toma alrededor de 570 MB, pero el tiempo dice 2.3 GB. En la práctica, ese número no es útil para mí.
Ole Tange
El factor 4 se fija en el tiempo GNU 1.7 y, por lo tanto, funciona como se esperaba.
Ole Tange
Nota importante: El "Tamaño máximo de conjunto residente" solo funciona desde Linux 2.6.32.
Jan Hudec
17

Tal vez exagere, pero acabo de descubrir que valgrindtiene una buena herramienta llamada massif. Lo probé en xterm:

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

Y obtienes un buen gráfico de uso de memoria:

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

junto con información de uso de memoria demasiado detallada. Detalles en el manual de valgrind .

Sin embargo, los programas se ejecutarán aproximadamente 20 veces más lento. Además, ejecuté algunos comandos dentro del xterm. Su huella de memoria se ha tenido en cuenta porque --trace-children=yesla opción está ahí.

Stéphane Gimenez
fuente
1
La penalización de velocidad 20x hace que sea inestimable para mi situación. De lo contrario, muy bonito gráfico!
Ole Tange
1
Parece que, al menos en la versión 3.8.1 de valgrind que estoy usando, los booleanos solo se aceptan en la forma "sí / no" y no "verdadero / falso". El mío se quejó! :-)
MakisH
6

Aunque el tema es bastante antiguo, quiero compartir otro proyecto que surgió de la función del núcleo cgroups Linux.

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

cgmemtime mide el uso de memoria RSS + CACHE en aguas altas de un proceso y sus procesos descendientes.

Para poder hacerlo, coloca el proceso en su propio cgroup.

Por ejemplo, el proceso A asigna 10 MiB y bifurca a un niño B que asigna 20 MiB y que bifurca a un niño C que asigna 30 MiB. Los tres procesos comparten una ventana de tiempo donde sus asignaciones dan como resultado el uso de memoria RSS (tamaño de conjunto residente) correspondiente.

La pregunta ahora es: ¿Cuánta memoria se usa realmente como resultado de ejecutar A?

Respuesta: 60 MiB

cgmemtime es la herramienta para responder a esas preguntas.

Vlad Frolov
fuente
3

Parece que tstime ya no funciona en sistemas no root en Linux> = 3.0. Aquí hay una utilidad de encuestas que escribí para hackear el problema: https://github.com/jhclark/memusg/blob/master/memusg

jhclark
fuente
/usr/bin/time -vda la salida correcta en versiones más nuevas. En versiones anteriores solo necesita dividir por 4 para obtener la cantidad correcta.
Ole Tange
Sin embargo, no creo que time -v admita el tamaño máximo de memoria (solo RSS). ¿Alguien puede confirmar esto en la última versión?
jhclark