Esto comienza un poco fuera de tema (y luego lo relacionaré con su pregunta), pero lo que está sucediendo es similar a lo que sucede cuando bifurca un proceso en Linux. Al bifurcar hay un mecanismo llamado copiar sobre escritura que solo copia el espacio de memoria para el nuevo proceso cuando la memoria también está escrita. De esta forma, si el ejecutor del proceso bifurcado es un nuevo programa de inmediato, habrá ahorrado la sobrecarga de copiar la memoria original de los programas.
Volviendo a su pregunta, la idea es similar. Como han señalado otros, al solicitar la memoria obtiene el espacio de la memoria virtual de inmediato, pero las páginas reales solo se asignan cuando se les escribe.
¿Cuál es el propósito de esto? Básicamente hace que la memoria mallocing sea una operación de tiempo más o menos constante Big O (1) en lugar de una operación Big O (n) (similar a la forma en que se distribuye el programador de Linux, en lugar de hacerlo en un gran bloque).
Para demostrar lo que quiero decir que hice el siguiente experimento:
[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
El programa bigmalloc asigna 20 millones de enteros, pero no hace nada con ellos. deadbeef escribe una int en cada página, lo que da como resultado 19531 escrituras y justwrites asigna 19531 ints y las elimina. Como puede ver, deadbeef tarda aproximadamente 100 veces más en ejecutarse que bigmalloc y unas 50 veces más que Justwrite.
#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;
}
¿Es lo mismo para windows? – TStamper
No estoy familiarizado con lo que Windows hace, lo siento. – bdonlan
bdonlan: Correcto, pero deben tener cuidado con el efecto de de tenedor "* El niño no hereda las cerraduras de memoria de su matriz (MLOCK (2), mlockall (2)) " Cuál será la forma más carga de aplicación cuando mira en la parte superior – RandomNickName42