4

我正在编写一个处理多个文件的程序,每个文件大小约为 6 GB(来自服务器的大日志文件)。但是我只使用了 25% 的 CPU(4 个可用的 CPU 线程中有 1 个),因为我无法将程序拆分为不同的线程,工作必须按顺序完成。

因此,我正在考虑同时处理多达 4 个文件,因为我有一个四核 CPU,但我受到 HDD 随机磁盘访问性能的限制。

但几天后,我将使用带 SSD 和 8 GB 内存的笔记本电脑。是否可以将每个文件的前 1 GB 映射到内存中并在 4 个不同的线程中处理它们?当我到达映射文件的末尾时,我应该能够在内存中映射下一个 1 GB 的文件以继续。我想对于 SSD 来说,将 1 GB 映射到内存应该不是问题,因为它的读取速度约为 400 MB/s。

我知道这可以使用 FileChannel 来完成,但我不确定是否只映射文件的一部分。

谢谢,西贝

4

3 回答 3

1

当您对文件进行内存映射时,这些文件实际上并未传输到内存(这与内存映射相反)。

相反,您会得到一个内核特别对待的内存地址;当您访问它时,内核会加载一个包含文件内容的内存页面。当操作系统决定回收一些内存时,这些页面就会被卸载;您可以将映射文件视为扩展的交换空间。

综上所述,只要你有足够的内存地址(也就是说,你有一个 64 位的操作系统和 JVM),你就可以映射一个比系统内存更大的文件。

于 2012-08-29T13:09:20.350 回答
0

您可以使用 FileChannel 一次将整个文件映射到内存中。但是,如果您是按顺序读取数据并且您的处理并不简单,那么在每个线程中使用普通的 FileInputStream 可能会更易于使用并为您提供大致相同的性能。

于 2012-08-29T12:33:14.547 回答
0

您想使用可以从 FileChannel 检索的 MemoryMappedByteBuffer。另请参阅:Java 中的内存映射文件和此:http ://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html

同样正如彼得指出的那样,如果您的处理不是 CPU 密集型的,那么在首先处理之前将文件移动到内存中可能不会获得太多收益。一口气做完可能会更好。如您所知,复制到内存不是免费的。

于 2012-08-29T12:39:30.263 回答