Copy-on-Write (COW)

Copy-on-write is the kernel optimisation that makes fork() fast. When a process calls fork(), the kernel does not copy the parent’s pages — it copies the page table and marks all shared pages read-only. When either process writes to a shared page, the MMU triggers a fault; the kernel makes a private copy of that page, marks it writable, and resumes execution. Each write-fault copies exactly one page (~4 KiB).

Why this matters

A 4 GiB process forks in microseconds. The RSS only climbs when pages are actually written. The classic demonstration:

char *buf = malloc(64 * 1024 * 1024);
memset(buf, 'A', 64*1024*1024);  // touch pages — now backed
pid_t pid = fork();
if (pid == 0) {
    memset(buf, 'B', 64*1024*1024);  // child's RSS climbs 64 MiB here
    printf("child: buf[0]='%c'\n", buf[0]);  // 'B'
    _exit(0);
}
waitpid(pid, NULL, 0);
printf("parent: buf[0]='%c'\n", buf[0]);  // 'A' — unchanged

The child’s memset causes 16,384 page faults (64 MiB / 4 KiB). The parent’s memory is unaffected.

Implication for students

Students who think fork() copies the process are surprised when:

  • A large process forks nearly instantly
  • The child’s RSS climbs dramatically after a write while the parent’s stays flat
  • Tools like smem show VSS vs. RSS diverging post-fork

In the curriculum

Covered in m07-processes-signals pedagogical notes and Key Code Examples. Also appears in m02-pointers-memory-model as context for virtual address spaces.

See also

fork, memory-layout, pointers