Virtual memory is what allows processes in a modern system to use memory without concern for other running code. Virtual memory is also what restricts processes from interferring with the memory used by other processes or by the OS itself.
Before the OS hands the processor over to a process, it configures the memory tables such that the process runs in a lowered state of privilege and an address specified in the process’s code is translated by the CPU into a different physical address in RAM. So addresses in a process’s code are actually virtual addresses, not physical addresses. As far as each process is concerned, it has the full range of addresses to use for itself.
This mapping from virtual addresses to physical is done in chunks called pages. On today’s x86 systems, the usual page size is 4KB.
When a process uses an address in a page which has not been mapped for it, this triggers a hardware exception usually called a pagefault (or segfault, “segmentation fault”: older processors used a memory scheme divided into segments, not pages, but the term segfault still persists).
When a page isn’t being used, the OS can swap it from RAM onto a hard drive. The next time the page is needed, it is swapped back out to RAM.
