Estoy un poco confundido sobre algunos de los resultados que estoy viendoPDygratis.
En mi servidor, este es el resultado defree -m
[root@server ~]# free -m
total used free shared buffers cached
Mem: 2048 2033 14 0 73 1398
-/+ buffers/cache: 561 1486
Swap: 2047 11 2036
Según tengo entendido, cómo Linux administra la memoria es que almacenará el uso del disco en la RAM, de modo que cada acceso posterior sea más rápido. Creo que esto lo indican las columnas "en caché". Además, se almacenan varios búferes en la RAM, como se indica en la columna "búferes".
Entonces, si entiendo correctamente, se supone que el uso "real" es el valor "usado" de "-/+ buffers/cache", o 561 en este caso.
Entonces, suponiendo que todo eso sea correcto, la parte que me desconcierta son los resultados de ps aux
.
Según tengo entendido ps
, los resultados son que la sexta columna (RSS) representa el tamaño en kilobytes que el proceso utiliza para la memoria.
Entonces, cuando ejecuto este comando:
[root@server ~]# ps aux | awk '{sum+=$6} END {print sum / 1024}'
1475.52
¿No debería el resultado ser la columna "usada" de "-/+ buffers/cache" de free -m
?
Entonces, ¿cómo puedo determinar correctamente el uso de memoria de un proceso en Linux? Aparentemente mi lógica es defectuosa.
Respuesta1
Copiar/pegar descaradamente mi respuesta defallo del servidorjusto el otro día :-)
El sistema de memoria virtual de Linux no es tan simple. No puedes simplemente sumar todos los campos RSS y obtener el valor informado used
por free
. Hay muchas razones para esto, pero mencionaré algunas de las más importantes.
Cuando un proceso se bifurca, tanto el padre como el hijo se mostrarán con el mismo RSS. Sin embargo, Linux emplea copia en escritura para que ambos procesos realmente utilicen la misma memoria. Sólo cuando uno de los procesos modifique la memoria, esta realmente se duplicará.
Esto hará que elfree
número sea menor que latop
suma RSS.El valor RSS no incluye la memoria compartida. Debido a que la memoria compartida no es propiedad de ningún proceso,
top
no la incluye en RSS.
Esto hará que elfree
número sea mayor que latop
suma RSS.
Hay muchas otras razones por las que las cifras podrían no cuadrar. Esta respuesta solo intenta señalar que la administración de la memoria es muy compleja y que no se pueden simplemente sumar/restar valores individuales para obtener el uso total de la memoria.
Respuesta2
Si está buscando números de memoria que sumen, eche un vistazo asmem:
smem es una herramienta que puede brindar numerosos informes sobre el uso de memoria en sistemas Linux. A diferencia de las herramientas existentes, smem puede informar el tamaño de conjunto proporcional (PSS), que es una representación más significativa de la cantidad de memoria utilizada por bibliotecas y aplicaciones en un sistema de memoria virtual.
Debido a que grandes porciones de memoria física generalmente se comparten entre múltiples aplicaciones, la medida estándar de uso de memoria conocida como tamaño de conjunto residente (RSS) sobreestimará significativamente el uso de memoria. En cambio, PSS mide la "participación justa" de cada aplicación en cada área compartida para dar una medida realista.
Por ejemplo aquí:
# smem -t
PID User Command Swap USS PSS RSS
...
10593 root /usr/lib/chromium-browser/c 0 22868 26439 49364
11500 root /usr/lib/chromium-browser/c 0 22612 26486 49732
10474 browser /usr/lib/chromium-browser/c 0 39232 43806 61560
7777 user /usr/lib/thunderbird/thunde 0 89652 91118 102756
-------------------------------------------------------------------------------
118 4 40364 594228 653873 1153092
También lo PSS
es la columna interesante aquí porque tiene en cuenta la memoria compartida.
A diferencia de RSS
lo significativo que es sumarlo. Aquí obtenemos un total de 654 MB para procesos en el espacio de usuario.
La salida de todo el sistema informa sobre el resto:
# smem -tw
Area Used Cache Noncache
firmware/hardware 0 0 0
kernel image 0 0 0
kernel dynamic memory 345784 297092 48692
userspace memory 654056 181076 472980
free memory 15828 15828 0
----------------------------------------------------------
1015668 493996 521672
Entonces, 1 Gb de RAM en total = 654 Mb de procesos en el área de usuario + 346 Mb de memoria del kernel + 16 Mb libres
(más o menos unos pocos Mb)
En general, aproximadamente la mitad de la memoria se utiliza para caché (494 Mb).
Pregunta extra: ¿Qué es aquí el caché del área de usuario versus el caché del kernel?
Por cierto, prueba algo visual:
# smem --pie=name
Respuesta3
Una herramienta realmente buena es pmap
la que enumera el uso actual de memoria para un determinado proceso:
pmap -d PID
Para obtener más información al respecto, consulte la página de manual man pmap
y también eche un vistazo a20 herramientas de monitoreo del sistema Linux que todo administrador de sistemas debería conocer, que enumera excelentes herramientas que siempre uso para obtener información sobre mi sistema Linux.
Respuesta4
Como otros han señalado correctamente, es difícil controlar la memoria real utilizada por un proceso, con regiones compartidas, archivos mmap y todo eso.
Si eres un experimentador, puedes ejecutarvalgrind y macizo. Esto puede resultar un poco complicado para el usuario ocasional, pero podrá hacerse una idea del comportamiento de la memoria de una aplicación con el tiempo. Si una aplicación malloc() es exactamente lo que necesita, esto le dará una buena representación del uso real de memoria dinámica de un proceso. Pero este experimento puede ser "envenenado".
Para complicar las cosas, Linux le permitecomprometerse demasiadotu memoria. Cuando malloc() memoria, estás indicando tu intención de consumir memoria. Pero la asignación no ocurre realmente hasta que escribes un byte en una nueva página de tu "RAM" asignada. Puedes comprobarlo tú mismo escribiendo y ejecutando un pequeño programa en C como este:
// test.c
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
void *p;
sleep(5)
p = malloc(16ULL*1024*1024*1024);
printf("p = %p\n", p);
sleep(30);
return 0;
}
# Shell:
cc test.c -o test && ./test &
top -p $!
Ejecute esto en una máquina con menos de 16 GB de RAM y, ¡listo!, ¡acaba de obtener 16 GB de memoria! (no en realidad no).
Observe que top
ve "VIRT" como 16.004G pero %MEM es 0.0
Ejecute esto nuevamente con valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
Y el macizo dice "suma de todas las asignaciones() = 16 GB". Entonces eso no es muy interesante.
PERO, si lo ejecutas en uncuerdoproceso:
# Shell:
rm test test.o
valgrind --tool=massif cc test.c -o test &
sleep 3
ms_print massif.out.$! | head -n 30
--------------------------------------------------------------------------------
Command: cc test.c -o test
Massif arguments: (none)
ms_print arguments: massif.out.23988
--------------------------------------------------------------------------------
KB
77.33^ :
| #:
| :@::@:#:
| :::::@@::@:#:
| @:: :::@@::@:#:
| ::::@:: :::@@::@:#:
| ::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| :@@@@@@@@@@@@@@@@@@@@:@::@:::@:::::@:: :::@@::@:#:
| :@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
0 +----------------------------------------------------------------------->Mi
0 1.140
Y aquí vemos (de forma muy empírica y con muy alta confianza) que el compilador asignó 77 KB de montón.
¿Por qué esforzarse tanto en conseguir solo un uso dinámico? Porque todos los objetos compartidos y secciones de texto que utiliza un proceso (en este ejemplo, el compilador) no son muy interesantes. Son una sobrecarga constante para un proceso. De hecho, las invocaciones posteriores del proceso casi son "gratuitas".
Además, compare y contraste lo siguiente:
MMAP() un archivo de 1GB. Su VMSize será 1+GB. Pero su tamaño de conjunto residente solo serán las partes del archivo en las que hizo que se paginaran (desreferenciando un puntero a esa región). Y si "lee" el archivo completo, cuando llegue al final, es posible que el kernel ya haya paginado el principio (esto es fácil de hacer porque el kernel sabe exactamente cómo y dónde reemplazar esas páginas si se desreferencian nuevamente). ). En cualquier caso, ni VMSize ni RSS son un buen indicador del "uso" de su memoria. En realidad, no has malloc()'ed nada.
Por el contrario, Malloc() y toque MUCHA memoria, hasta que su memoria se intercambie al disco. Entonces su memoria asignada ahora excede su RSS. Aquí, su VMSize podría comenzar a decirle algo (su proceso posee más memoria de la que realmente reside en su RAM). Pero todavía es difícil diferenciar entre VM que son páginas compartidas y VM que son datos intercambiados.
Aquí es donde valgrind/massif se vuelve interesante. Te muestra lo que tienesintencionalmenteasignados (independientemente del estado de sus páginas).