Como otros han señalado correctamente, es difícil controlar la memoria real utilizada por un proceso, con regiones compartidas y archivos mmap'ed y demás.
Si eres un experimentador, puedes ejecutar valgrind y macizo . Esto puede ser un poco pesado para el usuario casual, pero con el tiempo obtendrá una idea del comportamiento de la memoria de una aplicación. Si una aplicación malloc () es exactamente lo que necesita, esto le dará una buena representación del uso real de la memoria dinámica de un proceso. Pero este experimento puede ser "envenenado".
Para complicar las cosas, Linux le permite comprometer en exceso su memoria. Cuando malloc () memoria, estás indicando tu intención de consumir memoria. Pero la asignación realmente no sucede hasta que escribe un byte en una nueva página de su "RAM" asignada. Puedes probarte esto 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 $!
Ejecuta esto en una máquina con menos de 16 GB de RAM y, ¡listo !, acabas de obtener 16 GB de memoria! (no en realidad no).
Observe top
que ve "VIRT" como 16.004G pero% MEM es 0.0
Ejecute esto de nuevo con valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
Y el macizo dice "suma de todos los alocs () = 16GB". Entonces eso no es muy interesante.
PERO, si lo ejecutas en un proceso sensato :
# 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 (muy empíricamente y con mucha confianza) que el compilador asignó 77 KB de almacenamiento dinámico.
¿Por qué esforzarse tanto para obtener solo el uso del montón? Debido a que todos los objetos compartidos y las secciones de texto que usa un proceso (en este ejemplo, el compilador) no son terriblemente interesantes. Son gastos generales constantes para un proceso. De hecho, las invocaciones posteriores del proceso casi son "gratis".
Además, compare y contraste lo siguiente:
MMAP () un archivo de 1GB. Su tamaño de VMS será de 1 + GB. Pero su Tamaño de conjunto residente solo serán las partes del archivo en las que causó que se pagine (al desreferenciar un puntero a esa región). Y si "lee" todo el archivo, para cuando llegue al final, es posible que el núcleo ya haya paginado los comienzos (esto es fácil de hacer porque el núcleo sabe exactamente cómo / dónde reemplazar esas páginas si se desreferencia de nuevo ) En cualquier caso, ni VMSize ni RSS son un buen indicador del "uso" de su memoria. En realidad no has malloc () editado nada.
Por el contrario, Malloc () y toque MUCHA memoria, hasta que su memoria se cambie 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 aún es difícil diferenciar entre VM que son páginas compartidas y VM que son datos intercambiados.
Aquí es donde Valgrind / Macizo se pone interesante. Le muestra lo que ha asignado intencionalmente (independientemente del estado de sus páginas).
htop
autor a una pregunta similar que tuve el otro día ... Cómo calcular el uso de memoria desde / proc / meminfo (como htop)