javaclinuxiooperating-system

Why mmap() (Memory Mapped File) is faster than read()


I was working on something about MappedByteBuffer of Java NIO recently. I've read some posts about it and all of them mention that "mmap() is faster than read()".

In my conclusion:

  1. I treat MappedByteBuffer == Memory Mapped File == mmap()

  2. read() has to read data through: disk file -> kernel -> application, so it has context switch and buffer copying.

  3. They all said mmap() has less copying or syscall than read(), but as I know it also need to read from disk file the first time you access the file data. So the first time it read : virtual address -> memory -> page fault -> disk file -> kernel -> memory. Except you can access it randomly, the last 3 steps (disk file -> kernel -> memory) is exactly the same as read(), so how could mmap() be less copying or syscall than read()?

  4. What's the relationship between mmap() and swap file, Is that the OS will put the least used file data of memory into swap (LRU)? So when the second time you access these data, OS retrieves them from swap but not disk file (no need to copy to kernel buffer), that's why mmap() has less copying and syscall?

  5. In Java, MappedByteBuffer is allocated out of heap (it's a direct buffer). So when you read from MappedByteBuffer, does it mean it need one more extra memory copy from outside the Java heap into Java heap?

Could anyone answer my questions? Thanks :)


Solution

  • 1: Yes, that is essentially what a MappedByteBuffer is.

    2: "disk file -> kernel" doesn't necessarily involve copying.

    3: With a memory-mapped file, once the kernel has read the file into its cache, it can simply map that part of the cache into your process - instead of having to copy the data from the cache into a location your process specifies.

    4: If the kernel decides to swap out a page from a memory-mapped file, it will not write the page to the page file; it will write the page to the original file (the one it's mapped from) before discarding the page. Writing it to the page file would be unnecessary and waste page file space.

    5: Yes. For example, if you call get(byte[]) then the data will be copied from the off-heap mapping into your array. Note that functions such as get(byte[]) need to copy data for any type of buffer - this is not specific to memory-mapped files.