linux内核-写时复制之实验+源码分析

实验

相信大家都听过大名鼎鼎的copy on write技术,并且学习过原理。但是可能对于代码中具体的发生场景,脑海中可能没有实体的映射。下面使用1个例子说明copy on write的发生时间。

有这么一个程序:

#include 
#include 
#include 
#include 

// 打印当前进程的内存占用(常驻集大小)
void print_memory_usage(const char* stage) {
    FILE* file = fopen("/proc/self/status", "r");
    if (!file) {
        perror("fopen");
        return;
    }

    char line[256];
    while (fgets(line, sizeof(line), file)) {
        if (strncmp(line, "VmRSS:", 6) == 0) {
            printf("[%s] Memory Usage (VmRSS): %s", stage, line + 6);
            break;
        }
    }

    fclose(file);
}

int main() {
    size_t size = 100 * 1024 * 1024; // 分配 100 MB
    void* ptr = malloc(size);
    if (!ptr) {
        perror("malloc");
        return 1;
    }

    printf("Step 1: After malloc (before memset)\n");
    print_memory_usage("After malloc");
    sleep(3);  // 给用户一点时间观察

    memset(ptr, 0, size); // 写入触发物理内存分配

    printf("Step 2: After memset (after touching memory)\n");
    print_memory_usage("After memset");
    sleep(3);  // 给用户一点时间观察

    free(ptr);
    printf("Step 3: After free\n");
    print_memory_usage("After free");

    return 0;
}

编译+运行

编译:

gcc do_copy_on_write.c -o do_copy_on_write

运行:

./do_copy_on_write

各部分说明

1. 分配内存(malloc)

void* ptr = malloc(size);

分配了一块大小为 100MB 的虚拟内存。此时操作系统只分配了虚拟地址空间,并没有实际分配物理内存页(因为还没有使用它)。程序紧接着打印此时的内存使用情况(VmRSS):

print_memory_usage("After malloc");

2.让程序睡眠3秒

  • 程序会 sleep(3) 秒,可以有时间手动观察或记录当前内存(可以用 tophtop 或查看程序输出)。

  • 你会发现此时内存几乎没有明显增长,只有很小的常驻内存(程序自身的开销)。

3. 访问内存触发分配(memset)

memset(ptr, 0, size);
  • 使用 memset 将这 100MB 全部设置为 0,相当于每个内存页都被写入了一次

  • 这会触发操作系统的延迟物理页分配机制,因为每个页第一次被写入,就必须真正分配物理内存。

  • 然后再次调用 print_memory_usage 打印新的 VmRSS,这时你会看到内存暴涨到 100MB 左右

 4. 最后释放内存

整个程序完整的输出为:

./a.out
Step 1: After malloc (before memset)
[After malloc] Memory Usage (VmRSS):         952 kB
Step 2: After memset (after touching memory)
[After memset] Memory Usage (VmRSS):      103912 kB
Step 3: After free
[After free] Memory Usage (VmRSS):          1536 kB

源码分析

TODO

你可能感兴趣的:(linux内核-写时复制之实验+源码分析)