Descubrí que pidstat
sería una buena herramienta para monitorear procesos. Quiero calcular el uso promedio de memoria de un proceso en particular. Aquí hay un ejemplo de salida:
02:34:36 PM PID minflt/s majflt/s VSZ RSS %MEM Command
02:34:37 PM 7276 2.00 0.00 349212 210176 7.14 scalpel
(Esto es parte de la salida de pidstat -r -p 7276
).
¿Debo usar la información de Tamaño de conjunto residente (RSS) o Tamaño virtual (VSZ) para calcular el consumo promedio de memoria? He leído algunas cosas en Wikipedia y en foros, pero no estoy seguro de entender completamente las diferencias. Además, parece que ninguno de ellos es confiable. Entonces, ¿cómo puedo monitorear un proceso para obtener su uso de memoria?
Cualquier ayuda sobre este asunto sería útil.
Respuestas:
RSS es la cantidad de memoria que este proceso tiene actualmente en la memoria principal (RAM). VSZ es la cantidad de memoria virtual que tiene el proceso en total. Esto incluye todos los tipos de memoria, tanto en RAM como intercambiados. Estos números pueden sesgarse porque también incluyen bibliotecas compartidas y otros tipos de memoria. Puede tener quinientas instancias de
bash
ejecución, y el tamaño total de su huella de memoria no será la suma de sus valores RSS o VSZ.Si necesita tener una idea más detallada sobre la huella de memoria de un proceso, tiene algunas opciones. Puedes revisar
/proc/$PID/map
y eliminar las cosas que no te gustan. Si se trata de bibliotecas compartidas, el cálculo podría volverse complejo dependiendo de sus necesidades (que creo recordar).Si solo le importa el tamaño de almacenamiento dinámico del proceso, siempre puede analizar la
[heap]
entrada en elmap
archivo. El tamaño que el núcleo ha asignado para el montón del proceso puede o no reflejar el número exacto de bytes que el proceso ha pedido que se asigne. Hay detalles minuciosos, elementos internos del núcleo y optimizaciones que pueden estropear esto. En un mundo ideal, será todo lo que su proceso necesite, redondeado al múltiplo más cercano del tamaño de página del sistema (getconf PAGESIZE
le dirá cuál es: en las PC, probablemente sea de 4.096 bytes).Si desea ver cuánta memoria ha asignado un proceso , una de las mejores maneras es renunciar a las métricas del lado del kernel. En su lugar, se instrumentan las funciones de asignación (des) de memoria de montón de la biblioteca C con el
LD_PRELOAD
mecanismo. Personalmente, abuso un pocovalgrind
para obtener información sobre este tipo de cosas. (Tenga en cuenta que la aplicación de la instrumentación requerirá reiniciar el proceso).Tenga en cuenta que, dado que también puede comparar los tiempos de ejecución, eso
valgrind
hará que sus programas sean un poco más lentos (pero probablemente dentro de sus tolerancias).fuente
/proc/$PID/maps
es la diferencia de error tipográfico o de distribución?Ejemplo ejecutable mínimo
Para que esto tenga sentido, debe comprender los conceptos básicos de la paginación: https://stackoverflow.com/questions/18431261/how-does-x86-paging-work y, en particular, que el sistema operativo puede asignar memoria virtual a través de tablas de páginas / su contabilidad interna (memoria virtual VSZ) antes de que realmente tenga un almacenamiento de respaldo en RAM o disco (memoria residente RSS).
Ahora para observar esto en acción, creemos un programa que:
mmap
C Principal
GitHub aguas arriba .
Compilar y ejecutar:
dónde:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
: requerido para Linux para permitirnos hacer una llamada mmap más grande que la RAM física: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate/57687432#57687432Salida del programa:
Estado de salida:
que según la regla del número de señal 128+ significa que obtuvimos el número de señal
9
, queman 7 signal
dice que es SIGKILL , que es enviado por el asesino de memoria insuficiente de Linux .Interpretación de salida:
printf '0x%X\n' 0x40009A4 KiB ~= 64GiB
(losps
valores están en KiB) después del mmap.extra_memory_committed 0
, lo que significa que aún no hemos tocado ninguna página. RSS es un pequeño1648 KiB
que se ha asignado para el inicio normal del programa como área de texto, globales, etc.8388608 KiB == 8GiB
páginas por valor. Como resultado, RSS aumentó exactamente 8GIB a8390256 KiB == 8388608 KiB + 1648 KiB
Ver también: Necesito explicación sobre Tamaño de conjunto residente / Tamaño virtual
OOM troncos asesinos
Nuestros
dmesg
comandos han mostrado los registros asesinos de OOM.Se ha pedido una interpretación exacta de estos en:
La primera línea del registro fue:
Así que vemos que, curiosamente, fue el demonio MongoDB que siempre se ejecuta en mi computadora portátil en segundo plano lo que activó por primera vez al asesino OOM, presumiblemente cuando el pobre estaba tratando de asignar algo de memoria.
Sin embargo, el asesino OOM no necesariamente mata a quien lo despertó.
Después de la invocación, el núcleo imprime una tabla o procesos que incluyen
oom_score
:y más adelante vemos que nuestro propio pequeño
main.out
fue asesinado en la invocación anterior:Este registro menciona lo
score 865
que ese proceso tuvo, presumiblemente el puntaje más alto (peor) del asesino OOM como se menciona en: ¿Cómo decide el asesino OOM qué proceso matar primero?También es interesante que aparentemente todo sucedió tan rápido que antes de que se contara la memoria liberada, el proceso
oom
despertó nuevamenteDeadlineMonitor
:y esta vez que acabó con el proceso de Chromium, que suele ser la memoria normal de mi computadora:
Probado en Ubuntu 19.04, kernel de Linux 5.0.0.
fuente