为什么malloc()会导致较小的页面错误?
我试图了解内存和页面错误,所以我写了下面的代码来检查我的理解。我不明白为什么调用malloc会导致MINFL增加,因为malloc()不应该影响物理内存(据我所知) 这是我的代码:为什么malloc()会导致较小的页面错误?,c,malloc,virtual-memory,ps,page-fault,C,Malloc,Virtual Memory,Ps,Page Fault,我试图了解内存和页面错误,所以我写了下面的代码来检查我的理解。我不明白为什么调用malloc会导致MINFL增加,因为malloc()不应该影响物理内存(据我所知) 这是我的代码: #include <stdio.h> #include <stdlib.h> void main() { printf("Before malloc\n"); getchar(); malloc(1 << 20); printf(&quo
#include <stdio.h>
#include <stdlib.h>
void main() {
printf("Before malloc\n");
getchar();
malloc(1 << 20);
printf("After malloc\n");
getchar();
}
#包括
#包括
void main(){
printf(“在malloc之前”);
getchar();
马洛克(1答案非常简单。Glibcmalloc
将使用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);
}
i、 e.getrusage
和printf
第一次导致页面错误,所以我们称之为两次-现在计数是118;在malloc
之后计数是119。如果你看指针,0x010不是0x000,即分配不是页面对齐的-前16个字节包含free的簿记信息e> 这样它就知道需要使用munmap
来释放内存块及其大小
现在,这很自然地解释了为什么大小增加了1028 Ki而不是1024 Ki-必须保留一个额外的页面,以便有足够的空间容纳这16个字节!这也解释了页面错误的来源-因为malloc
必须在写零页面上将簿记信息写入副本。这可以通过写入分配的第一个字节来证明这一点——它不再导致页面错误
最后,for循环将修改页面,并在映射到的257页面中触摸剩余的256页。为什么MINFL会增加。如果不查看实现细节,很难确定。但通常malloc
将读/写内存以维护其数据结构(例如,已用和空闲列表).Somalloc
实际上是写入内存。这对我来说是新的。谢谢。谢谢你详细解释了页面错误的原因,我一开始不理解它。@Orielno我进一步改进了它。这很清楚。谢谢
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