如何解决为什么 malloc() 会导致小页面错误?
我正在尝试了解内存和页面错误,所以我编写了下面的代码来检查我的理解。我不明白为什么调用 malloc 会导致 MINFL 增加,因为 malloc() 不应该影响物理内存(据我所知)。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
void main() {
printf("Before malloc\n");
getchar();
malloc(1 << 20);
printf("After malloc\n");
getchar();
}
这些是ps命令的终端结果。
有两件事我不明白:
请帮忙,谢谢。
解决方法
答案很简单。 Glibc malloc
将使用 mmap
直接分配大于 128 KiB 的块。但是,它需要在指针下方写簿记信息——因为如果只给出一个指针,free
怎么会知道它应该做什么。如果你打印指针,你会发现它没有页面对齐:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/resource.h>
int main(void) {
struct rusage usage = {0};
getrusage(RUSAGE_SELF,&usage);
printf("1st before malloc: %lu\n",usage.ru_minflt);
getrusage(RUSAGE_SELF,&usage);
printf("2nd before malloc: %lu\n",usage.ru_minflt);
char *p = malloc(1 << 20);
printf("pointer returned from malloc: %p\n",p);
getrusage(RUSAGE_SELF,&usage);
printf("after malloc: %lu\n",usage.ru_minflt);
p[0] = 42;
getrusage(RUSAGE_SELF,&usage);
printf("after writing to the beginning of the allocation: %lu\n",usage.ru_minflt);
for (size_t i = 0; i < (1 << 20); i++) {
p[i] = 42;
}
getrusage(RUSAGE_SELF,&usage);
printf("after writing to every byte of the allocation: %lu\n",usage.ru_minflt);
}
输出类似
1st before malloc: 108
2nd before malloc: 118
pointer returned from malloc: 0x7fbcb32aa010
after malloc: 119
after writing to the beginning of the allocation: 119
after writing to every byte of the allocation: 375
即getrusage
和 printf
第一次导致页面错误,所以我们调用它两次 - 现在计数是 118;在 malloc
之后,计数为 119。如果您查看指针,0x010 不是 0x000,即分配不是页对齐的 - 前 16 个字节包含 free
的簿记信息,以便它知道它需要使用 munmap
来释放内存块,以及它的大小。
现在这自然解释了为什么大小增加是 1028 Ki 而不是 1024 Ki - 必须保留一个额外的页面,以便有足够的空间容纳这 16 个字节!它还解释了页面错误的来源 - 因为 malloc
必须将簿记信息写入写入时复制归零的页面。这可以通过写入分配的第一个字节来证明 - 它不再导致页面错误。
最后,for 循环将修改页面并触及映射到的 257 个页面中剩余的 256 个页面。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。