What Is a Memory-Mapped File? How mmap Lets Linux Programs Work With Files Like Memory

A diverse group of IT professionals examining Linux systems and server hardware in a modern data-center lab.

A memory-mapped file lets a program work with file-backed data through ordinary memory addresses instead of repeatedly calling read() or write() for every chunk. On Linux, the key system call is mmap().

The easiest mental model is: Linux connects part of a file to part of a process’s virtual address space. The program can then access that region as if it were memory, while the kernel handles the relationship between virtual addresses, RAM, the page cache, and the file on storage.

mmap Does Not Mean “Copy The Whole File Into RAM”

One of the most common misunderstandings is that mapping a 20 GB file instantly loads all 20 GB into physical memory. That is not how normal demand-paged systems work. mmap() establishes a mapping in the process’s virtual memory; the kernel can bring file-backed pages into RAM when the program actually touches them.

The official Linux mmap(2) manual page defines mmap() as creating a new mapping in the calling process’s virtual address space. That distinction matters because a mapping reserves and describes address-space relationships before every byte necessarily exists in RAM.

A File Descriptor Opens The Door

For a normal file-backed mapping, a program first opens the file and receives a file descriptor. The program then passes that descriptor to mmap(), along with a length, offset, requested memory protections, and mapping flags.

int fd = open("data.bin", O_RDONLY);
void *p = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);

mmap() itself is a system call. It asks the kernel to create a virtual-memory region backed by a file or another supported object.

The First Touch Can Trigger A Page Fault

Suppose the mapping exists but the program has not touched a particular page yet. When code first reads from an address in that mapped region, the CPU may discover that the required page is not currently present in the process’s page tables. That generates a page fault.

The kernel then determines what belongs at that virtual address. For a file-backed mapping, it can obtain the corresponding file data, connect the physical page to the process, update the page tables, and resume the instruction. From the program’s point of view, it simply accessed memory.

Jacob Sorber demonstrates memory-mapped file I/O in C and shows how a program can access file contents through a mapped memory region.

mmap And The Page Cache Work Together

Memory-mapped file I/O is closely tied to the Linux page cache. The page cache holds file-backed data in RAM so repeated access can often avoid another trip to the storage device.

This means buffered read() I/O and memory-mapped I/O are not two completely separate universes. Both can ultimately work with file-backed pages that Linux caches in memory. The difference is primarily in how the application addresses and accesses that data.

MAP_PRIVATE And MAP_SHARED Are Very Different

Two of the most important mapping modes are MAP_PRIVATE and MAP_SHARED.

  • MAP_PRIVATE: changes made through the mapping are private to the process. Linux can use copy-on-write behavior so writes do not update the underlying file.
  • MAP_SHARED: changes can be visible to other processes mapping the same region and can propagate to the underlying file according to the operating system’s writeback and synchronization rules.

The POSIX mmap specification describes the mapping relationship between a process address space and a memory object. That general model is why memory mapping can support ordinary files, shared memory, and other operating-system facilities.

Why Developers Use Memory-Mapped Files

Memory mapping can simplify programs that need random access to large files. Instead of manually seeking, allocating a separate buffer, reading a chunk, keeping track of offsets, and repeating the process, code can often treat the mapped region like an array of bytes or structured records.

This can be especially attractive for large indexes, model weights, databases, binary assets, scientific data, compilers, and operating-system tools. It can also reduce some explicit copying and buffering work, although whether it is actually faster depends heavily on access pattern, filesystem behavior, storage, memory pressure, and implementation details.

A programming-community discussion around llama.cpp highlights a practical use of mmap for loading very large model weights efficiently.

Memory Mapping Can Also Share Data Between Processes

With an appropriate shared mapping, two processes can map the same underlying object and communicate through shared pages instead of copying an entire payload through a pipe or socket. Synchronization is still required when multiple processes can modify the same data, because shared memory does not automatically solve race conditions.

Mappings also interact with process creation. Linux preserves mappings across fork() with the same mapping attributes, which is one reason copy-on-write and shared-memory behavior are central operating-system concepts.

Files Still Have Filesystem Metadata

Memory mapping does not replace the filesystem. The file still has metadata, permissions, ownership, size, timestamps, and an inode. The mapping simply gives the process a memory-oriented way to access file-backed contents.

If another process truncates a file while a mapping still covers addresses beyond the new end of that file, access can fail dramatically. On Linux, touching an invalid portion of a file-backed mapping can result in SIGBUS. That is one reason memory mapping requires careful ownership and lifecycle rules.

mmap Is Not Automatically Faster

Memory mapping is powerful, but it is not a universal performance switch. Sequential buffered I/O can already be extremely efficient. The kernel performs read-ahead, caching, writeback, and other optimizations for ordinary file access.

A mapping can also generate many page faults, create virtual-memory-area overhead, complicate error handling, and behave poorly when access patterns are sparse or unpredictable. Large mappings compete for cache residency just like other file-backed pages. Benchmark the real workload instead of assuming that mmap() wins by definition.

How To See A Process’s Mappings

Linux exposes a process’s current memory mappings through /proc. You can inspect your shell’s mappings or another process you have permission to examine.

cat /proc/$$/maps

# or
cat /proc/<PID>/maps

The output shows address ranges, permissions, file offsets, device and inode information, and the mapped pathname when one exists. That makes /proc/<PID>/maps one of the simplest ways to connect virtual-memory theory to a real running Linux process.

Two IT professionals reviewing Linux memory and storage activity beside open server hardware in a data center.
Memory-mapped files connect file-backed storage to a process’s virtual address space so the program can work with file data through memory addresses.

What Happens When The Mapping Is Finished

A process can remove a mapping with munmap(). When the process exits, its mappings are also torn down. Unmapping removes that virtual-address relationship; it does not mean Linux must immediately evict every corresponding file-backed page from the page cache.

For writable shared mappings, applications that require strong durability guarantees need to understand synchronization and storage semantics rather than assuming that a memory store is already safely committed to persistent media.

The Short Version

A memory-mapped file lets Linux connect file-backed data to a process’s virtual address space. mmap() creates the mapping, page faults can bring needed pages into RAM, the page cache can hold file-backed data, and mapping flags determine whether writes are private or shared.

The sentence to remember is: mmap lets a program address file data like memory, while the kernel manages the paging, caching, and file-backed relationship underneath.

Editor’s Note

This evergreen explains the practical Linux memory-mapping model. Exact performance, fault behavior, filesystem semantics, and durability requirements vary by kernel version, filesystem, architecture, and workload.

BitcoinVersus.Tech is independently maintained. Support options on the site help fund additional technical research, verification, and open educational publishing.

BitcoinVersus.tech is not a financial advisor. Content is provided for informational purposes.

One response to “What Is a Memory-Mapped File? How mmap Lets Linux Programs Work With Files Like Memory”

  1. […] also appears with private memory-mapped files. A mapping created with MAP_PRIVATE can initially reflect file-backed pages, but changes made […]

    Like

Leave a Reply