0

使用 a 读取文件Mapped FileChannel似乎快如闪电......但我想知道他们是如何做到这一点的?

他们只是在一个大的(~64kB)缓冲区中读取,然后让我通过它吗?或者还有更多?

我只是对速度印象深刻,并想更好地理解它背后的算法。

4

2 回答 2

2

在您阅读之前,他们不会阅读任何内容,然后您阅读的内容基本上是通过操作系统分页系统阅读的。打开可能几乎不会花费您,但重复读取文件的同一部分可能会导致重复 I/O。没有什么是免费的。

于 2012-12-16T08:57:16.727 回答
1

内存映射,将文件映射到您的内存中,Java 提供了一个库来包装它,因此您可以相对安全地访问它。

它的好处包括:

  • 在内存、操作系统磁盘缓存和应用程序内存中只有一个副本。
  • 您无需系统调用即可访问文件的随机区域。
  • Java 确实限制了您可以映射的数量。即,如果您的最大堆为 1 GB,而您的最大直接内存为 1 GB,您仍然可以在 1 TB 中进行映射。

它的缺点包括:

  • 它会消耗虚拟内存,如果您重新映射或关闭文件,它不会返回。如果您有一个 64 位 JVM,这不是这样的问题,但如果您有一个可能只有 1 GB 可用空间的 32 位 JVM,那么这个问题就非常有限。它在 GC 运行时释放虚拟内存。
  • 它一次读取/写入至少一页。如果您有很多随机访问,这可能会很好,但如果您正在读取/写入磁盘上的许多文件,这实际上会减慢顺序访问的速度。一次随机附加到许多文件 4KB 可能会导致高度碎片化的文件,这是不明智的。
  • 使用内存映射文件可能比使用普通的 DataXxxxStream 或 BufferedReader/Writer 更加困难。

我已经编写了几个库,使内存映射文件更易于使用,我会说我会在超低延迟至关重要或您需要读取大量内存时使用它,这些内存您希望已经在磁盘缓存中并且您想要充分利用您的磁盘缓存。

值得注意的是,内存映射不会使您的磁盘子系统更快,如果这是您的限制因素,那么您读取/写入数据的方式并不重要。

于 2012-12-16T10:12:14.273 回答