Come altri hanno giustamente sottolineato, è difficile ottenere un handle sulla memoria effettiva utilizzata da un processo, cosa con le aree condivise, i file mmap e quant'altro.
Se sei uno sperimentatore, puoi eseguire valgrind e massiccio . Questo potrebbe diventare un po 'pesante per l'utente occasionale, ma ti verrà un'idea del comportamento della memoria di un'applicazione nel tempo. Se un'applicazione malloc () è esattamente ciò di cui ha bisogno, questo ti darà una buona rappresentazione dell'utilizzo reale della memoria dinamica di un processo. Ma questo esperimento può essere "avvelenato".
A complicare le cose, Linux ti consente di sovraccaricare la tua memoria. Quando malloc () memoria, dichiari il tuo intento di consumare memoria. Ma l'allocazione non avviene realmente finché non si scrive un byte in una nuova pagina della "RAM" allocata. Puoi dimostrarlo scrivendo ed eseguendo un piccolo programma C in questo modo:
// 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 $!
Eseguilo su una macchina con meno di 16 GB di RAM e, voilà !, hai appena ottenuto 16 GB di memoria! (no, non proprio).
Notare in top
te "VIRT" come 16.004G ma% MEM è 0.0
Esegui di nuovo con valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
E il massiccio dice "somma di tutte le risorse () = 16 GB". Quindi non è molto interessante.
MA, se lo esegui su un processo sano :
# 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
E qui vediamo (molto empiricamente e con la massima fiducia) che il compilatore ha allocato 77 KB di heap.
Perché provare così tanto per ottenere solo un utilizzo dell'heap? Perché tutti gli oggetti condivisi e le sezioni di testo utilizzate da un processo (in questo esempio il compilatore) non sono tremendamente interessanti. Sono costanti costi generali per un processo. In effetti, le successive invocazioni del processo arrivano quasi per "libero".
Inoltre, confronta e confronta quanto segue:
MMAP () un file da 1 GB. Il tuo VMSize sarà 1 + GB. Ma sei Resident Set Size saranno solo le parti del file in cui hai fatto il paging (dereferenziando un puntatore a quella regione). E se "leggi" l'intero file allora, quando arriverai alla fine, il kernel potrebbe aver già eseguito il paging degli inizi (questo è facile da fare perché il kernel sa esattamente come / dove sostituire quelle pagine se nuovamente referenziato ). In entrambi i casi, né VMSize né RSS sono un buon indicatore del "utilizzo" della memoria. In realtà non hai malloc () ed ed nulla.
Al contrario, Malloc () e tocca MOLTA memoria - fino a quando la memoria non viene scambiata su disco. Quindi la tua memoria allocata ora supera il tuo RSS. Qui, il tuo VMSize potrebbe iniziare a dirti qualcosa (il tuo processo possiede più memoria di ciò che risiede effettivamente nella RAM). Ma è ancora difficile distinguere tra VM che è pagine condivise e VM che è scambiata dati.
Qui è dove valgrind / massiccio diventa interessante. Ti mostra ciò che hai allocato intenzionalmente (indipendentemente dallo stato delle tue pagine).
htop
dell'autore a una domanda simile che ho avuto l'altro giorno ... Come calcolare l'utilizzo della memoria da / proc / meminfo (come htop)