Uso máximo de memoria de un proceso Linux / Unix


376

¿Existe una herramienta que ejecute una línea de comandos e informe el uso total de RAM máximo?

Me estoy imaginando algo análogo a / usr / bin / time

Respuestas:


28

Aquí hay una línea que no requiere scripts o utilidades externas y no requiere que inicie el proceso a través de otro programa como Valgrind o tiempo, por lo que puede usarlo para cualquier proceso que ya se esté ejecutando:

grep VmPeak /proc/$PID/status

(reemplazar $PIDcon el PID del proceso que le interesa)


44
¿Qué pasa si no sé PID? Por ejemplo, en caso de que el programa ejecute una pequeña cantidad de tiempo (<1s)
diralik

44
"VmHWM: tamaño máximo de conjunto residente" podría ser más útil para medir el uso de RAM (en lugar de VmPeak que incluye muchas otras cosas también).
jfs

@jfs realmente depende de lo que quieras descubrir. IIRC VmPeak es el uso máximo de memoria total, incluida la memoria virtual, mientras que VmHWM es el uso máximo de RAM. Entonces, si desea saber la cantidad total de memoria que ha solicitado su programa, use VmPeak; si desea saber qué cantidad de RAM real ha usado en un momento dado, use VmHWM.
erobertc

1
@diralik si está revisando un programa escrito por usted mismo, puede incrustar una línea de código para buscar en el archivo "/ proc / self / status".
Fileland

405

[ Editar : funciona en Ubuntu 14.04: /usr/bin/time -v command asegúrese de utilizar la ruta completa.]

Parece /usr/bin/timeque te da esa información, si la pasas -v(esto está en Ubuntu 8.10). Ver, por ejemplo, a Maximum resident set sizecontinuación:

$ / usr / bin / time -v ls /
....
        Comando cronometrado: "ls /"
        Tiempo de usuario (segundos): 0.00
        Tiempo del sistema (segundos): 0.01
        Porcentaje de CPU que obtuvo este trabajo: 250%
        Tiempo transcurrido (reloj de pared) (h: mm: ss o m: ss): 0: 00.00
        Tamaño promedio de texto compartido (kbytes): 0
        Tamaño promedio de datos no compartidos (kbytes): 0
        Tamaño de pila promedio (kbytes): 0
        Tamaño total promedio (kbytes): 0
        Tamaño máximo del conjunto residente (kbytes): 0
        Tamaño promedio del conjunto residente (kbytes): 0
        Fallos de página principales (que requieren E / S): 0
        Fallos de página menores (reclamar un marco): 315
        Cambios de contexto voluntarios: 2
        Cambios de contexto involuntarios: 0
        Swaps: 0
        Entradas del sistema de archivos: 0
        Salidas del sistema de archivos: 0
        Mensajes de socket enviados: 0
        Mensajes de socket recibidos: 0
        Señales entregadas: 0
        Tamaño de página (bytes): 4096
        Estado de salida: 0

44
Probablemente siempre devuelve 0 porque ls no está haciendo mucho. Pruebe un comando más intensivo de CPU.
Jon Ericson

17
Desde la página de manual: La mayoría de la información que se muestra por tiempo se deriva de la llamada al sistema wait3 (2). Los números son tan buenos como los devueltos por wait3 (2). En los sistemas que no tienen una llamada wait3 (2) que devuelve información de estado, en su lugar se utiliza la llamada al sistema times (2). Sin embargo, proporciona mucha menos información que wait3 (2), por lo que en esos sistemas el tiempo informa que la mayoría de los recursos es cero.
lothar

79
"bash: -v: comando no encontrado" significa que bash intercepta el tiempo para usar el suyo. /bin/time -vlo resuelve
gcb

3
Valdría la pena hacer una comprobación rápida para asegurarse de que la salida tenga sentido. El tiempo de GNU tiene un error en el que informará 4 veces el uso de memoria real: stackoverflow.com/questions/10035232/…
Ian

24
@skalee Probar time -len MacOS, ofrece resultados similares.
Volker Stolz

96

(Esta es una pregunta antigua ya respondida ... pero solo para el registro :)

Me inspiró el guión de Yang y se me ocurrió esta pequeña herramienta, llamada memusg . Simplemente aumenté la frecuencia de muestreo a 0.1 para manejar procesos de vida muy cortos. En lugar de monitorear un solo proceso, lo hice medir la primera suma del grupo de procesos. (Sí, escribo muchos programas separados que funcionan juntos) Actualmente funciona en Mac OS X y Linux. El uso tenía que ser similar al de time:

memusg ls -alR /> / dev / null

Solo muestra el pico por el momento, pero estoy interesado en pequeñas extensiones para registrar otras estadísticas (aproximadas).

Es bueno tener una herramienta tan simple para echar un vistazo antes de comenzar cualquier perfil serio.


1
todo lo que todavía usa PS y solo sirve para determinar la memoria superior observada. No es la memoria superior real. siempre puedes perderte algo entre un intervalo y otro.
gcb

66
¿Cuáles son las unidades para la salida del script memusg? Bytes? Kilobytes?
Daniel Standage

1
@DanielStandage: probablemente en Kilobytes. Simplemente observa los valores mostrados por ps -o rss=donde rss es el tamaño de la memoria real (conjunto residente) del proceso (en unidades de 1024 bytes) desde mi página de manual de BSD.
netj

3
@gcb Y qué, eso es lo que obtienes cuando estás midiendo muestras.
Volker Stolz

2
El enlace a memusg dado en la respuesta parece estar roto. De todos modos, / usr / bin / time lo hace muy 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

Tenga en cuenta el uso de --pages-as-heap para medir toda la memoria en un proceso. Más información aquí: http://valgrind.org/docs/manual/ms-manual.html


14
time, Te estoy dejando.
jbeard4

1
Guión práctico, pero necesito sort -g en mi sistema Slackware (supongo que está buscando el valor más alto).
Nick Coleman el

3
+1 para valgrind --massif. También puede usar la ms_printherramienta que viene con ella para obtener resultados útiles (incluyendo gráficos ascii de uso a lo largo del tiempo)
Eli Bendersky

77
El macizo tiene una sobrecarga mucho más alta que timesin embargo, tomando al menos 10 veces más tiempo en un comando como ls.
Timothy Gu

8
Es demasiado masivo de hecho. Esta respuesta debería mencionar la desaceleración. El comando que quiero medir normalmente tarda 35 segundos en completarse. Ejecuté este comando valgrind para medirlo hace más de media hora, y aún no se ha completado ...
unagi

35

En Linux:

Use /usr/bin/time -v <program> <args>y busque " Tamaño máximo de conjunto residente ".

(No debe confundirse con el Golpe timecomando integrado! Así que utilice la ruta completa , /usr/bin/time)

Por ejemplo:

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

En BSD, MacOS:

Uso /usr/bin/time -l <program> <args>, buscando " tamaño máximo de conjunto residente ":

>/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
¿Acaso este terreno ya no está cubierto por una respuesta agregada dos años antes ?
Charles Duffy

34

Quizás (gnu) el tiempo (1) ya hace lo que quieres. Por ejemplo:

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

Pero otras herramientas de creación de perfiles pueden proporcionar resultados más precisos según lo que esté buscando.


Parece que siempre obtengo ceros con esto, incluso para comandos grandes
jes5199

Obtengo resultados variables, como 400% 0 y 0% 0 en el mismo programa ... ¿tal vez debería ejecutarse durante períodos de tiempo más largos para ser exactos?
Liran Orevi

No se que sugerir. El código anterior es exactamente lo que obtuve al ejecutar un comando de látex que resultó estar en la historia. Como digo, se pueden obtener resultados más precisos con otras herramientas.
Jon Ericson

2
Eso funciona al menos en sistemas CentOS (y, por lo tanto, apuesto a que también RHEL). % P proporciona estadísticas no relacionadas (% CPU) que depende del planificador y, por lo tanto, es bastante variable.
Blaisorblade

2
@Deleteman: timees un comando integrado cuando se usa csh. Si usa la ruta exacta, le permitirá ejecutar el comando externo. Hasta donde sé, solo la versión GNU admite la opción de formato.
Jon Ericson

18

/ usr / bin / time tal vez hace lo que quieres, en realidad. Algo como.

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

Vea el tiempo (1) para más detalles ...


1
Parece que siempre obtengo ceros con esto, incluso para comandos grandes
jes5199

jes5199, Liran, mirando a los comentarios anteriores parece que el tiempo (1) puede ser roto por la presentación de informes de memoria en algunos Linuxes ...
Simon

En Ubuntu 16.04, el texto y los datos son cero, pero max no es cero y produce un valor significativo. Estoy feliz con eso
Stéphane Gourichon

Espero que Mmax signifique lo que queremos que signifique ... la página del manual es un poco escueta al respecto
matanster

17

En MacOS Sierra use:

/usr/bin/time -l commandToMeasure

Puede usar greppara tomar lo que quiera, tal vez.


55
¡Esta! Literalmente, pasé una hora tratando de obtener Instruments.app y dtrace para darme un perfil de memoria con la integridad del sistema activada (no se puede desactivar), mientras que todo lo que necesitaba era este simple comando. Una pequeña nota, puede usar en command time -llugar de lo /usr/bin/time -lque hará que su shell realmente llame a un binario llamado en timelugar de la función incorporada. (Sí, commandno es un marcador de posición, command timees diferente de solo time).
Jakub Arnold

16

Si el proceso se ejecuta durante al menos un par de segundos, puede usar el siguiente script bash, que ejecutará la línea de comando dada y luego imprimirá para stderr el pico RSS (sustituya rsscualquier otro atributo que le interese). Es algo ligero y funciona para mí con el psincluido en Ubuntu 9.04 (que no puedo decir 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
El principal inconveniente de este método es que si el proceso asigna mucha memoria durante un período corto (por ejemplo, cerca del final), esto puede no detectarse. Reducir el tiempo de sueño puede ayudar un poco.
vinc17


8

Bueno, si realmente desea mostrar el pico de memoria y algunas estadísticas más detalladas, le recomiendo usar un generador de perfiles como valgrind . Un buen front-end valgrind es alleyoop .



5

Aquí hay (basado en las otras respuestas) un script muy simple que observa un proceso que ya se está ejecutando. Simplemente lo ejecuta con el pid del proceso que desea ver 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

Ejemplo de uso:

max_mem_usage.sh 23423


1

Heaptrack es una herramienta de KDE que tiene una interfaz gráfica de usuario y una interfaz de texto. Me parece más adecuado que valgrind comprender el uso de memoria de un proceso porque proporciona más detalles y gráficos de llamas. También es más rápido porque controla menos ese valor. Y te da el uso máximo de memoria.

De todos modos, el seguimiento de rss y vss es engañoso porque las páginas podrían compartirse, por eso memusg. Lo que realmente debe hacer es realizar un seguimiento de la suma de Pssin /proc/[pid]/smapso use pmap. El monitor de sistema GNOME solía hacerlo, pero era demasiado costoso.


1

Reinventar la rueda, con guión de bash hecho a mano. Rápido y limpio.

Mi caso de uso: quería monitorear una máquina Linux que tiene menos RAM y quería tomar una instantánea del uso por contenedor cuando se ejecuta bajo un uso intensivo.

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

Salida de muestra:

2017-10-12 13:29:33: Ejecución de monitor de memoria libre con umbral 30%.

2017-10-12 13:29:33: Suficiente memoria libre disponible: 69.4567%

2017-10-12 13:30:03: Suficiente memoria libre disponible: 69.4567%

2017-10-12 16:47:02: memoria libre 18.9387% es inferior al 30%

su salida de comando personalizado


1

En macOS, puede usar DTrace en su lugar. La aplicación "Instrumentos" es una buena GUI para eso, viene con XCode afaik.



-2

Asegúrate de responder la pregunta. ¡Proporcione detalles y comparta su investigación!

Lo siento, estoy aquí por primera vez y solo puedo hacer preguntas ...

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

entonces:

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

Esto es muy diferente de lo que topmuestra el comando en un momento similar:

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

¿Cuáles son las unidades medidas de Valgrind?

La /usr/bin/time -v ./test.shcontestado a - debe alimentar directamente ejecutable /usr/bin/timecomo:

/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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.