malloc和calloc都是动态分配堆内存的函数,但calloc在分配完以后还会对这块内存进行初始化为零,而malloc不会对内存进行初始化 so,既然要初始化内存,那么就分配了物理内存,是由page-fault分配的物理内存吗 ?
malloc分配内存
函数原型:void *malloc(size_t size);
众所周知,malloc分配的内存(虚拟内存),都是没有和物理内存建立映射的,只有在实际去使用这块内存的时候,才会触发缺页中断page-fault,才会和物理内存的映射,映射的大小通常是4KB。
假如有一块1024 * 4 * 1024 字节的内存的话,全部使用则会触发1024次缺页中断。
//分配大小1024 *4 * 1024的内存
char* p = (char*)malloc(1024 *4 * 1024); //只是分配的虚拟内存,没有和物理内存建立映射
....
//使用这块内存,就会触发1024次缺页中断
//memset(p, 0, 1024 * 4 * 1024);
gcc编译并使用 perf 查看page-fault 数量 :
gcc test.cpp -o test & perf stat -e page-faults ./test
使用这块内存
//分配大小1024 *4 * 1024的内存
char* p = (char*)malloc(1024 *4 * 1024); //只是分配的虚拟内存,没有和物理内存建立映射
....
//使用这块内存,就会触发1024次缺页中断
memset(p, 0, 1024 * 4 * 1024);
同样编译并使用perf输出:
对比可以得出结论,malloc只负责分配虚拟内存,但并没有和物理内存建立映射关系,只有实际使用的时候才会映射。
calloc分配内存
函数原型:void *calloc(size_t nmemb, size_t size);
分配 nmemb * size 大小的物理内存,并初始化这块内存为零。
//分配1024 * 1024 * 4 的内存
char* p = (char*)calloc(1024, 1024 * 4);
gcc编译并使用 perf 查看page-fault 数量 :
gcc test.cpp -o test & perf stat -e page-faults ./test
可以发现,只调用calloc函数,就发生了1073 - 49 = 1024 次page-fault。
得出结论,calloc在分配内存后就会建立与物理内存的映射关系,相当于 malloc + memset的组合。
总结
1、malloc 、calloc等分配内存的函数,都是分配的虚拟内存,不是物理内存,不是物理内存,不是物理内存。
2、malloc只负责分配虚拟内存,不会建立和物理内存的映射。实际使用的时候才会page-fault建立映射。
3、calloc负责分配内存,建立与物理内存的映射,并且初始化这块内存为零。 相当于malloc + memset 。