我正在尝试了解内存映射的基础知识。 我编写了以下小程序:它分配一些作为参数传递的字节,然后不断设置字节直到程序终止:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
printf("pid = %d\n", getpid());
double mb = strtod(argv[1], NULL);
size_t bytes = 1000 * mb;
printf("allocating %f mb, or %ld bytes\n", mb, bytes);
char* ptr = (char*)malloc(bytes);
printf("allocated at %p\n", ptr);
size_t i=0;
while (1) {
for (i=0; i<bytes; i++) {
ptr[i] = 'a';
}
}
return 0;
}
当我运行./a.out 10000
时然后pmap <pid> -X
对应的pid
,我发现ptr从0x7ff9cf753010
开始但堆的显示如下:
Address Perm Offset Device Inode Size Rss Pss Referenced Anonymous LazyFree ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible Mapping
559eba856000 rw-p 00000000 00:00 0 132 4 4 4 4 0 0 0 0 0 0 0 0 0 [heap]
7ff9cf753000 rw-p 00000000 00:00 0 9768 9768 9768 9768 9768 0 0 0 0 0 0 0 0 0
我很困惑,因为大小是 9768,而不是 10,000。我猜 132 位是堆的某种 header ?另外,指针值不一样......希望对此有任何清晰的说明。
最佳答案
您看到的大小差异实际上并不像您想象的那样大小差异,这是因为 k
被用来表示 1000
和 1024
与表示字节的 B
结合使用,有时使用 Ki
来专门表示 1024
,但情况并非总是如此,尤其是在较旧的版本中接口(interface)。
如果您记住这一点并再次查看大小,您会发现 9768
正是您以 KiB 为单位分配的大小,四舍五入到页面大小的最接近倍数(通常为 4KiB): 10,000,000/1024 = 9765.625
四舍五入为 9768
。
指针 7ff9cf753000
与 7ff9cf753010
的区别在于 malloc
使用的簿记 header ,您将丢失的字节归咎于此。
关于检查 malloc 是否正在使用 pmap 分配所有内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75794489/