Я дав цю відповідь у подібному дописі на ту ж тему:
Деякі розподільники ледачі?
Це починається трохи з теми (і тоді я прив’яжу це до вашого запитання), але те, що відбувається, подібно до того, що відбувається, коли ви розгалужуєте процес у Linux. При розгалуженні існує механізм, який називається copy on write, який копіює простір пам'яті для нового процесу лише тоді, коли пам'ять теж записується. Таким чином, якщо розгалужений процес виконує нову програму відразу, ви зберегли накладні витрати на копіювання пам'яті оригінальних програм.
Повертаючись до вашого запитання, ідея схожа. Як зазначали інші, запит на пам’ять негайно отримує простір віртуальної пам’яті, але фактичні сторінки виділяються лише при записі на них.
Яка мета цього? В основному це робить помилки з пам'яті більш-менш постійною операцією часу Big O (1) замість операції Big O (n) (подібно до того, як планувальник Linux поширює свою роботу, замість того, щоб робити це одним великим шматком).
Щоб продемонструвати, що я маю на увазі, я провів наступний експеримент:
rbarnes@rbarnes-desktop:~/test_code$ time ./bigmalloc
real 0m0.005s
user 0m0.000s
sys 0m0.004s
rbarnes@rbarnes-desktop:~/test_code$ time ./deadbeef
real 0m0.558s
user 0m0.000s
sys 0m0.492s
rbarnes@rbarnes-desktop:~/test_code$ time ./justwrites
real 0m0.006s
user 0m0.000s
sys 0m0.008s
Програма bigmalloc виділяє 20 мільйонів інтів, але нічого з ними не робить. deadbeef записує по одному int на кожну сторінку, в результаті чого 19531 пише і justwrites виділяє 19531 ints і обнуляє їх. Як бачите, виконувальна робота займає приблизно в 100 разів більше часу, ніж bigmalloc, і приблизно в 50 разів довша, ніж просто написання.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000);
return 0;
}
.
#include <stdlib.h>
int main(int argc, char **argv) {
int *big = malloc(sizeof(int)*20000000);
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);
return 0;
}