据我所知,MappedByteBuffer有几个好处,例如:
它将用户空间内存地址映射到内核空间内存地址,以便在从文件读取时避免从内核空间到用户空间的内存复制
在第一次读取文件中的一块(等于缓冲区中从0到100的偏移量)之后,这块将被缓存在内存中,所以当你第二次读取同一块时缓冲区,你是直接从内存中读取它,而不是从磁盘中读取它。
我的问题是:
我的理解是否正确?
如果我的理解是正确的,当你只读一次这个片段时(从不再读它,因此它不能从内存中读取它),使用FileChannel.read(缓冲区,位置)是否相同使用MappedByteBuffer.get(byte [],offset,length)?
对于随机访问文件(不重复阅读同一篇文章),FileChannel会更有效率,因为MappedByteBuffer会占用它映射的内存而FileChannel不需要内存吗?
我使用MappedByteBuffer和我只是将整个文件加载到我的内存之间有什么区别。 MappedByteBuffer的好处是它使用JVM堆外部的内存,所以没有GC关注?
答案 0 :(得分:2)
让我逐一回答你的问题。
据我所知,MappedByteBuffer有几个好处,例如:
它将用户空间内存地址映射到内核空间内存地址,以便在从文件读取时避免从内核空间到用户空间的内存复制
- 醇>
在第一次读取文件中的一块(等于缓冲区中从0到100的偏移量)之后,这块将被缓存在内存中,所以当你第二次读取同一块时缓冲区,你是直接从内存中读取它,而不是从磁盘中读取它。
您的陈述无效。 但是,重要的是不要错过简单的事实。文件数据的访问始终涉及缓存(except when it does not)。如果内存映射来自缓存的页面映射到您的地址空间,则涉及FileChannel额外的内存复制。
如果我的理解是正确的,当你只读一次(从不再读它,因此它不会从内存中读取它)时,使用FileChannel.read(缓冲区,位置)和使用MappedByteBuffer是否相同。 get(byte [],offset,length)?
不,FileChannel.read(缓冲区,位置)涉及额外的内存复制。无论如何,数据将在缓存中挂起一段时间。
对于随机访问文件(不重复读取同一块),FileChannel会更有效率,因为MappedByteBuffer会占用它映射的内存,而FileChannel不需要内存吗?
您的推理不正确。使用数据访问模式,FileChannel为内存副本执行额外的内存,MappedByteBuffer不会。 另外,内存映射本质上是懒惰的。只有在访问相应的内存页时才会从磁盘加载数据。
我使用MappedByteBuffer之间有什么区别,我只是将整个文件加载到我的内存中。 MappedByteBuffer的好处是它使用JVM堆外部的内存,所以没有GC关注?
您可以在框上映射大于物理内存的数量级的文件(单个MappedByteBuffer限制为2GiB,因此需要多个映射)。通过映射的文件数据访问页面可以随时被OS收回。 实际上,就GC而言,MappedByteBuffer并不占用堆。
使用内存映射数据还有其他令人讨厌的含义。
这使得MappedByteBuffer成为一种奇特的,很少使用的方式来访问数据。
如果建议您避免 MappedByteBuffer