![](/img/trans.png)
[英]Why does the page fault not cause the thread to finish its execution later?
[英]Why does malloc() cause minor page fault?
我正在嘗試了解 memory 和頁面錯誤,所以我寫了下面的代碼來檢查我的理解。 我不明白為什么調用 malloc 會導致 MINFL 增加,因為 malloc() 不應該影響物理 memory (據我了解)。
這是我的代碼:
#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
來釋放memory 塊,及其大小。
現在自然這就解釋了為什么大小增加了 1028 Ki 而不是 1024 Ki - 必須保留一個額外的頁面,以便為這 16 個字節提供足夠的空間! 它還解釋了頁面錯誤的來源 - 因為malloc
必須將簿記信息寫入寫時復制歸零頁面。 這可以通過寫入分配的第一個字節來證明——它不再導致頁面錯誤。
最后 for 循環將修改頁面並觸及映射到的257個頁面中的剩余 256 個頁面。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.