devutils/ATFQ/book ATFQ git

Part I · How it works

1.3 How virtual memory works

alsovirtual memorypage faultpage faultsmmutlbpage tablepage tablessegfaultsegmentation faulthuge pagesthp

TL;DR

  • Every process sees its own memory, as if it were alone: the addresses it uses are virtual.
  • The CPU's MMU translates them into real RAM through page tables the kernel keeps, one page (usually 4 KiB) at a time.
  • Memory is only handed out when first touched: the first access to a page causes a page fault, and the kernel maps a page then.
cat /proc/self/maps | head            # a process's memory map
grep -E '^pg(maj)?fault ' /proc/vmstat

On your machine

alice@laptopexample
$ atfq 1.3
  Page      4.0 KiB
  Faults    809.6 million served from RAM, 2.4 million that read the disk,
            since boot
  Swap      15.6 MiB read back, 256.0 MiB written out
  Huge pages transparent huge pages: madvise

An example: Alice's laptop, one of the test machines. In your terminal, this block shows your own machine, read live.

Pitfalls

Deep dive 2 questions

Why not let programs use real addresses?

Isolation first: a process can't read or break another's memory. Then freedom for the kernel: it can place pages anywhere, share identical ones (libraries, or a process and its fork until one writes), move rarely used ones to swap, and give every program the same simple layout.

What are the TLB and huge pages?

Reading the page tables on every memory access would be slow, so the CPU keeps recent translations in a small cache, the TLB. With 4 KiB pages, a big program needs many entries; a huge page (2 MiB on x86-64) covers 512 times more with one. Transparent huge pages let the kernel use them by itself: always, only where a program asks (madvise), or never.

Commands
ps top
Paths
/proc/PID/maps /proc/PID/smaps /proc/vmstat
See also
17. Memory
17.4 The page cache
17.3 Swap and swappiness
1.5 How a program starts: fork and exec