Questo inizia un po 'fuori tema (e poi lo collegherò alla tua domanda), ma quello che sta succedendo è simile a quello che succede quando batti un processo in Linux. Quando forking c'è un meccanismo chiamato copy on write che copia solo lo spazio di memoria per il nuovo processo quando viene scritta anche la memoria. In questo modo se il processo biforcato esegue un nuovo programma subito dopo hai salvato il sovraccarico di copia della memoria dei programmi originali.
Tornando alla tua domanda, l'idea è simile. Come altri hanno sottolineato, richiedendo la memoria si ottiene immediatamente lo spazio di memoria virtuale, ma le pagine effettive vengono allocate solo quando si scrive su di esse.
Qual è lo scopo di questo? Fondamentalmente rende la memoria di mallocing un'operazione di tempo più o meno costante Big O (1) invece di un'operazione di Big O (n) (simile al modo in cui lo scheduler di Linux si espande, ma invece di farlo in un unico grosso pezzo).
Per dimostrare quello che voglio dire che ho fatto il seguente esperimento:
[email protected]:~/test_code$ time ./bigmalloc
real 0m0.005s
user 0m0.000s
sys 0m0.004s
[email protected]:~/test_code$ time ./deadbeef
real 0m0.558s
user 0m0.000s
sys 0m0.492s
[email protected]:~/test_code$ time ./justwrites
real 0m0.006s
user 0m0.000s
sys 0m0.008s
Il programma bigmalloc assegna 20 milioni di interi, ma non fa nulla con loro. deadbeef scrive un int in ogni pagina risultante in 19531 scritture e justwrites assegna 19531 pollici e li azzera. Come puoi vedere, deadbeef impiega circa 100 volte di più rispetto a bigmalloc e circa 50 volte di più rispetto ai justwrites.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes
return 0;
}
.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes
// immediately write to each page to simulate all at once allocation
// assuming 4k page size on 32bit machine
for (int* end = big + 20000000; big < end; big+=1024) *big = 0xDEADBEEF ;
return 0;
}
.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = calloc(sizeof(int),19531); // number of writes
return 0;
}
fonte
2009-05-14 18:46:38
è lo stesso per Windows? – TStamper
Non ho familiarità con ciò che fa Windows, mi dispiace. – bdonlan
bdonlan: Corretto, ma dovrebbe guardare fuori per l'effetto della forcella "* Il figlio non eredita i blocchi memoria del suo genitore (MLOCK (2), mlockall (2)) " Quale sarà come la maggior parte del carico di app quando sta guardando in alto – RandomNickName42