It is said that mmap()
maps files to the memory, and it costs to the virtual address space memory of the calling process. Does it really copy data to the memory, or the data still exists in the disk? Is mmap()
faster than read()
?
-
2What do you mean. Of course data resides on the disk, and of course data must be copied to memory to be accessed by your program (either with mmap or other methods). – Jack Sep 12 '12 at 08:22
4 Answers
The only thing the mmap
function really does is change some kernel data structures, and possibly the page table. It doesn't actually put anything into physical memory at all. After you call mmap
, the allocated region probably doesn't even point to physical memory: accessing it will cause a page fault. This kind of page fault is transparently handled by the kernel, in fact, this is one of the kernel's primary duties.
What happens with mmap
is that the data remains on disk, and it is copied from disk to memory as your process reads it. It can also be copied to physical memory speculatively. When your process gets swapped out, the pages in the mmap
region do not have to be written to swap because they are already backed by long-term storage -- unless you have modified them, of course.
However, mmap
will consume virtual address space, just like malloc
and other similar functions (which mostly use mmap
behind the scenes, or sbrk
, which is basically a special version of mmap
). The main difference between using mmap
to read a file and read
to read a file is that unmodified pages in an mmap
region do not contribute to overall memory pressure, they are almost "free", memory wise, as long as they are not being used. In contrast, files read with the read
function will always contribute to memory pressure whether they are being used or not, and whether they have been modified or not.
Finally, mmap
is faster than read
only in the use cases which it favors -- random access and page reuse. For linearly traversing a file, especially a small file, read
will generally be faster since it does not require modifying the page tables, and it takes fewer system calls.
As a recommendation, I can say that any large file which you will be scanning through should generally be read in its entirety with mmap
on 64-bit systems, and you can mmap
it in chunks on 32-bit systems where virtual memory is less available.
See also: mmap() vs. reading blocks
See also (thanks to James): When should I use mmap for file access?

- 1
- 1

- 205,541
- 37
- 345
- 415
The data still exists on the disk. The OS allocates some physical memory and copies file data into it so you access the file contents there (that happens when you try to access file data). That physical memory is mapped into the virtual address space of the process. The OS can unmap long unused portions of the file and it will map them back when needed. If there's little free physical memory, unmaps can be more aggressive, leading to poor performance.
Memory mapping of files:
uses less physical memory and virtual address space than simple "file reads/writes" because there are no file buffers here and there (in the OS, in the C standard library and in your program) and there's no unnecessary copying between them.
can be (
and probably is, if you have enough free physical memoryin certain conditions, depending on how much data we're talking about and how much physical memory the OS lets us use for mmap'ing) faster than simple "file reads/writes" because of the above and because you avoid transitions between the user and kernel modes that the "file read" system call involves. The only transitions that remain are those to map a specific page that's currently unmapped, they are initiated by page faults (=CPU exceptions), which are handled in the kernel. As long as everything you need is mapped, there are no user-kernel transitions while accessing file data.

- 61,140
- 12
- 83
- 180
-
The `mmap` method of reading files is only faster in certain cases, "probably" is certainly too strong an assertion. Unlike `read`, `mmap` requires heavier system calls, changing the page table, and requires generating page faults in order to read the data. With `read`, if the data is already in the disk cache the system call can return almost immediately with no "back and forth" between the kernel and user space. – Dietrich Epp Sep 12 '12 at 08:41
-
@DietrichEpp I think it all depends on how much data we're talking about and how much physical memory the OS lets us use for mmap'ing. If everything's in the physical memory, no user-kernel transitions are necessary to access the data. – Alexey Frunze Sep 12 '12 at 08:44
-
"It depends" is exactly my point -- but you are assuming that the kernel modifies the page table immediately (which has a cost), rather than defer it (which has a different cost). – Dietrich Epp Sep 12 '12 at 08:47
-
@DietrichEpp Thanks, removed "probably", added "in certain conditions...". – Alexey Frunze Sep 12 '12 at 08:52
-
No one has mentioned the hardware paging unit. That will help, won't it? – cdarke Sep 12 '12 at 10:50
-
@cdarke It's implied by the very words: `page fault`, `(un)map`, `virtual address`. – Alexey Frunze Sep 12 '12 at 10:52
"virtual memory" of a process is the range of addresses available to it. To make something available in memory, you need to reserve a range of addresses, so mmap()
takes up some virtual memory.
Under Linux (and many other systems probably use similar mechanism), when reading a file, the content is first read into memory allocated by kernel (in Linux this is the "page cache"). Than if you use mmap()
, this memory is simply made available to the process by assigning it some address in that process' address space. If you use read()
, the process allocates a buffer, which needs both addresses (virtual memory) and a place to live (physical memory) and the data get copied from the page cache to that buffer (more physical memory is needed).
The data is only read from disk when actually accessed. In mmap()
case it means when you actually address the memory, in read()
it is the copy to your buffer, so inside the read()
call.
Thus mmap()
is more efficient for large files, especially for random access. The disadvantages are that it can only be used for files and not file-like objects (pipes, sockets, devices, /proc files etc.) and that an IO failure is detected during the page-fault, where they are difficult to handle (it sends SIGBUS signal), while read can return error and the application can try to recover (most don't anyway). The later is mainly concern for network filesystems where IO failure might be because of lost connection.

- 73,652
- 13
- 125
- 172
-
1The `mmap` method of reading files is only more efficient in certain cases, due to the expense of modifying page tables, invalidating buffers, and the additional context switches between user space and kernel space. Also, failed IO on a region returned from `mmap` only causes a program crash if you use the default signal handler for `SIGBUS` -- handling `SIGBUS` allows you to recover from IO failures connected with `mmap`. – Dietrich Epp Sep 12 '12 at 08:44
Copying does not imply that the original is destroyed.
It maps the contents of the disk into memory, so of course at some point the bits must be copied, yes.
And since this means it needs address space, that occupies part of the process' virtual address space.

- 391,730
- 64
- 469
- 606
-
1There is good explanation here: [When should I use mmap for file access?](http://stackoverflow.com/questions/258091/when-should-i-use-mmap-for-file-access) – James Sep 12 '12 at 08:40