A PageFault is triggered by the MMU when it intercepts a memory access by a process in an OperatingSystem with VirtualMemory.
It may do so for a number of reasons:
- The page in which the offending address lies has not been mapped to physical memory by the OperatingSystem. Most frequently, that's because the content of the page has been written to HardDisk, and the page is unmapped for this process and mapped in another's address space which needs more memory. This is called swapping out the page in question. The PageFault handler in the Kernel resolves this situation by swapping out another page in a currently dormant process, loading the content of the current process's swapped out page into the now free page, and mapping this page into the process's address space at the right location. Then, it resumes the process which was interrupted by the PageFault, which doesn't notice nary a thing of these happenings. To it, it appears as if its memory access succeeded without a hitch.
- Sometimes, again, the page is not mapped to physical memory. However, in this case no memory was ever allocated to it at that stretch in its address space. This type of PageFault is known as a SegmentationFault.
- Similarly, a SegmentationFault may happen if the process tried to write to read-only or execute-only memory, or to read from execute-only memory.
- Sometimes, attempting to write to a read-only page is actually part of normal operation. In particular, creating a new process on Unix systems happens by duplicating the running process by way of the fork(2) system call. In order to avoid excessive fork(2) runtime cost of yore, modern Kernels don't copy the entire memory used by the forked process, but rather implement transparent CopyOnWrite by marking all the pages shared between several processes as read-only. When a process PageFaults by trying to write to such a shared page, the processes are given individual copies of that page, marked read-write this time. Again the process which was interrupted by the PageFault is resumed and continues execution as if its memory access succeeded in the first place.