In operating system design, virtual memory is an abstraction that represents a process’ address space in the system. From the perspective of the process, they control the entire memory space of the system. Virtual memory addresses don’t necessarily correspond to the same physical address. This is to allow different processes to use the same memory addresses.
There are three-main goals of virtual memory:
- Opacity — the process shouldn’t be aware that the memory is virtualised.
- Efficiency — the overhead associated with address translation must be fast (wrt time and space). This is done via hardware support.
- Protection — processes should be isolated from each other. Faulty processes should not be able to affect other running processes.
The main mechanism used is address translation between physical and virtual addresses. Hardware is done to efficiently translate at a low-level. The OS will manage the memory, by keeping track of which blocks are free and which are in use, i.e., how the memory is allocated.
Hardware-side
The number of usable virtual addresses may differ depending on the ISA. For example, in RISC-V, we are allowed a maximum of 39 bits for 512 GB of addressable memory usable by the system.
The memory management unit (MMU) is a hardware component in the CPU that functions to transform from a virtual to physical address.
OS-side
-
allows us to move process’ physical memory location without affecting their virtual memory
-
bound registers:
- holds size of the address space
- or holds physical address of the end of the address space
- this is saved and restored during context switches
-
physical memory: array of slots, track which one is free/ in use
-
i.e., free list
-
when process terminates, OS Puts memory back onto free list and cleans up associated data structures
-
when process is waiting, it’s possible to move the process’ address space to another location in memory
-
OS must also provide exception handlers for common exceptions, like out of bound accesses
internal fragmentation: discrete blocks will probably have lots of unused space
OS-side
On POSIX systems, we can use the mmap syscall to manage process’ virtual memory. It maps files to a process’ virtual address space. It returns a pointer (virtual address) that allows us to access the file directly.
mmapjust sets up the page tables and doesn’t read from the file, i.e., it just creates an invalid PTE but keeps track of where on the disk the file chunk is.- Then, when we access it first, it generates a page fault. Only then would the kernel read that entry into memory. This basically ensures only the parts of the file that are used get read into memory.
note distinction betw private, anonymous, shared