[英]Why mmap() (Memory Mapped File) is faster than read()
我最近正在研究Java NIO的MappedByteBuffer。 我已经阅读了一些关于它的帖子,所有人都提到“mmap()比read()更快”
在我的结论中:
我对待MappedByteBuffer == Memory Mapped File == mmap()
read()必须通过以下方式读取数据:磁盘文件 - >内核 - >应用程序,因此它具有上下文切换和缓冲区复制
他们都说mmap()比read()具有更少的复制或系统调用,但据我所知,它还需要在您第一次访问文件数据时从磁盘文件中读取。 所以第一次读它:虚拟地址 - >内存 - >页面错误 - >磁盘文件 - >内核 - >内存。 除了你可以随机访问它,最后3个步骤(磁盘文件 - >内核 - >内存)与read()完全相同,那么mmap()如何比read()更少复制或系统调用?
mmap()和交换文件之间的关系是什么,os是否会将最少使用的内存文件数据放入交换(LRU)? 因此,当您第二次访问这些数据时,操作系统会从交换但不是磁盘文件中检索它们(不需要复制到内核缓冲区),这就是为什么mmap()复制和系统调用较少的原因?
在java中,MappedByteBuffer是从堆中分配的(它是一个直接缓冲区)。 所以当你从MappedByteBuffer中读取时,是否意味着它需要从Java堆外部再添加一个额外的内存副本到java堆中?
谁能回答我的问题? 谢谢 :)
1:是的,这基本上就是MappedByteBuffer。
2:“磁盘文件 - >内核”不一定涉及复制。
3:使用内存映射文件,一旦内核将文件读入其缓存,它就可以简单地将缓存的那部分映射到您的进程中 - 而不必将数据从缓存复制到您的进程指定的位置。
4:如果内核决定从内存映射文件中换出页面,它将不会将页面写入页面文件; 在丢弃页面之前,它会将页面写入原始文件(从中映射的文件)。 将其写入页面文件将是不必要的并浪费页面文件空间。
5:是的。 例如,如果调用get(byte[])
则数据将从堆外映射复制到数组中。 请注意,诸如get(byte[])
函数需要复制任何类型缓冲区的数据 - 这不是特定于内存映射文件的。
你在比较苹果和橘子。 mmap()
'比read()
更快,因为它不执行任何I / O. 当您访问由映射产生的内存地址时,I / O将延迟到。 该 I / O是一样一样read(),
并且不管是 I / O快于read()
是一个很有争议的问题。 在我接受之前,我希望看到一个合适的基准。
我对待
MappedByteBuffer
== Memory Mapped File ==mmap()
好。
read()
必须通过以下方式读取数据:磁盘文件 - >内核 - >应用程序,因此它有两次上下文切换和缓冲区复制
相比什么?
他们都说mmap()比
read(),
有更少的复制或系统调用read(),
它具有较少的系统调用。 它是否具有较少的复制取决于实现。 当然可以通过DMA直接读取和写入数据,但特定的操作系统是否是特定于操作系统的。
但据我所知,它还需要在您第一次访问文件数据时从磁盘文件中读取。
正确。
所以第一次读它:虚拟地址 - >内存 - >页面错误 - >磁盘文件 - >内核 - >内存。 除了你可以随机访问它,最后3个步骤(磁盘文件 - >内核 - >内存)与read()完全相同,那么mmap()如何比read()更少复制或系统调用?
因为DMA,如果实现的话。
mmap()和交换文件之间的关系是什么
分配给映射的内存是进程地址空间的一部分,它是虚拟的,并且需要进行交换,并且交换文件中必须有空间,就像任何其他内存一样。
是os将把最少使用的内存文件数据放入交换(LRU)?
没有。
因此,当您第二次访问这些数据时,操作系统会从交换但不是磁盘文件中检索它们(不需要复制到内核缓冲区),这就是为什么mmap()复制和系统调用较少的原因?
不。做所有这些都是错的。
在java中,
MappedByteBuffer
是从堆中分配的(它是一个直接缓冲区)。
这没有意义。 直接缓冲区不会从堆中分配,它们由mmap()
或平台API分配,作为新内存。 不在堆中。 MappedByteBuffer
是直接缓冲区是正确的。
所以当你从MappedByteBuffer中读取时,是否意味着它需要从Java堆外部再添加一个额外的内存副本到java堆中?
是的,但不是出于上述原因。 原因是你必须调用MappedByteBuffer.get()/put(),
这本身就是一个额外的步骤。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.