【发布时间】:2015-05-20 17:52:29
【问题描述】:
我最近正在研究 Java NIO 的 MappedByteBuffer。 我读过一些关于它的帖子,他们都提到“mmap() 比 read() 快”
在我的结论中:
我对待 MappedByteBuffer == Memory Mapped File == mmap()
read() 必须通过:磁盘文件->内核->应用程序读取数据,因此它具有上下文切换和缓冲区复制
-
他们都说 mmap() 的复制或系统调用比 read() 少,但据我所知,它还需要在您第一次访问文件数据时从磁盘文件中读取。所以第一次读取:虚拟地址->内存->页面错误->磁盘文件->内核->内存。除了可以随机访问之外,最后 3 步(磁盘文件 -> 内核 -> 内存)与 read() 完全相同,那么 mmap() 如何比 read() 更少复制或系统调用?
mmap() 和swap 文件有什么关系,操作系统是否会将内存中使用最少的文件数据放入swap(LRU)?因此,当您第二次访问这些数据时,操作系统会从交换而不是磁盘文件中检索它们(无需复制到内核缓冲区),这就是 mmap() 复制和系统调用较少的原因?
在 java 中,MappedByteBuffer 是在堆外分配的(它是一个直接缓冲区)。那么当您从 MappedByteBuffer 读取时,是否意味着它需要从 java 堆外部向 java 堆多复制一份内存?
有人可以回答我的问题吗?谢谢:)
【问题讨论】:
-
对于第 4 部分,OS 磁盘缓存似乎也考虑在内。
-
除了使用模式的最终性能优势之外,内存映射文件比堆缓冲区更适合共享机器。内存映射文件可以在操作系统需要回收物理内存时保存和取消映射,并在程序再次访问时透明地重新映射。
标签: java c linux io operating-system