Memory-mapped file 2026-10-13
A memory-mapped file makes a range of a file accessible through an operating-system process's virtual memory address space. Once the mapping exists, ordinary loads and stores address its contents instead of explicitly reading them into a separate application buffer. This is attractive for jumping between records in a large file: an offset becomes an address calculation, and demand paging can supply the needed memory pages. It removes the application's explicit read-and-copy step; it does not promise that every access avoids copying, input-output, page faults or overhead, or that mapping is universally faster.
The backing file, page cache contents and each operating-system process's page table play different roles. For ordinary buffered Linux kernel mappings, the page cache holds reusable file contents; normal reads and writes also use it. A valid mapping can exist before this operating-system process has a usable page table entry. A first load can therefore trigger a page fault even when another reader has already brought the contents into computer memory. If the contents are absent, servicing the page fault can require input-output; if present, the handler can install an address translation without that read. Special paths that bypass the page cache are outside this explanation.[ref]
The following example and diagrams are an original toy model, not an actual benchmark or a trace of a running operating system. They assume ordinary buffered file mappings, successful accesses, two cooperating operating-system processes, no concurrent resizing, and explicitly ordered actions. Memory-mapped file offset translation explains where the accesses land; shared file mappings and private file mappings explain whose contents change; memory-mapped file synchronization explains the separate persistence boundary.
Let be the memory page size, the aligned starting file offset, the mapping length and its base virtual address. A valid displacement with corresponds to file offset
Here is the relative memory page index, the floor function selects its integer part, and Euclidean division gives the within-page displacement . The backing page begins at . This identifies file contents; the page table separately selects a resident page frame and enforces permissions.
Take , and bytes in a file of at least 12288 bytes. A has a shared file mapping at . B has a shared file mapping at and a private file mapping at . These bases are illustrative chosen results, not requested fixed addresses. All three mappings cover the same two backing pages: file offsets 4096–8191 and 8192–12287. Displacement selects relative page 1, within-page displacement 37 and file offset . Thus A's 0x10001025, B's shared 0x20001025 and B's private 0x30001025 initially identify the same byte. The adjacent displacement 4134 identifies file offset 8230. Different virtual addresses can reach the same backing contents.
Figure 1.
Two operating-system processes map two backing pages at different virtual addresses; displacement 4133 identifies file offset 8229
. Details.
To access a requested file offset that is not aligned, choose and displacement . Mapping enough bytes to cover that displacement plus the requested length makes the desired data start inside the aligned mapping. Do not pass the unaligned directly as the Linux kernel mmap offset. For example, uses and displacement 37; that one-page start differs from our two-page mapping's .
Private file mapping 2026-10-14
With MAP_PRIVATE, copy-on-write initially reuses backing page cache contents. In our model, a private store raises a protection page fault, copies the affected memory page to a private page frame, installs a writable page table entry and retries. The other memory page can remain shared. This page fault needs no storage read.
In B's private file mapping, storing copies relative page 1, including its neighbor . Next, A stores through its shared file mapping. After coordination outside the mapped data, B's shared reads give , while its detached private page gives . The untouched first memory page remains backed by the file; this is not a frozen snapshot of the whole file. Neither page writeback of shared contents nor msync publishes B's private 99. To save those private contents, the application needs a separate explicit file update.
Figure 1.
Toy shared file mapping and copy-on-write timeline: visible shared changes precede the chosen durable completion; private changes remain separate
. Details.
Shared file mapping 2026-10-14
With MAP_SHARED, updates are visible to other operating-system processes mapping the same region and are carried through to the backing file. With MAP_PRIVATE, updates instead stay private, and later backing file changes have unspecified visibility in that mapping.[ref]
In the toy model, both shared file mappings initially read backing bytes at file offsets 8229 and 8230. Both memory pages have been accessed, so their translations are installed. A shared store changes the common page cache contents and creates a dirty memory page eligible for page writeback. That change can be observed before it reaches persistent storage. Cooperating readers need synchronization to know when an update is ready; MAP_SHARED alone supplies no mutual exclusion or indivisible multi-field update.