首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java NIO MappedByteBuffer OutOfMemoryException

Java NIO MappedByteBuffer OutOfMemoryException
EN

Stack Overflow用户
提问于 2012-09-21 21:56:09
回答 4查看 7K关注 0票数 6

我真的有麻烦了:我想使用FileChannelMappedByteBuffer读取超过几GB的大文件-我找到的所有文档都表明使用FileChannel.map()方法映射文件相当简单。当然,2 2GB是有限制的,因为所有的缓冲区方法都使用int来表示位置、限制和容量--但是系统隐含的限制在2 2GB以下又如何呢?

实际上,我得到了很多关于OutOfMemoryExceptions的问题!而且没有任何文档真正定义了这些限制!那么,如何才能将符合int-limit的文件安全地映射到一个或多个MappedByteBuffer中,而不只是得到异常呢?

在我尝试FileChannel.map()之前,我可以询问系统我可以安全地映射文件的哪一部分吗?多么?为什么关于这个特性的文档如此之少??

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-22 05:54:51

文件越大,你就越不想一次将其全部存储在内存中。设计一种方法,一次处理一个缓冲区,一次处理一行,等等。

MappedByteBuffers尤其有问题,因为没有定义的映射内存释放,因此一次使用多个内存本质上肯定会失败。

票数 2
EN

Stack Overflow用户

发布于 2012-09-21 22:05:36

我可以提供一些工作代码。很难说这是否能解决你的问题。这将在文件中搜索Hunter所识别的模式。

有关原始研究(不是我的),请参阅优秀的文章Java tip: How to read files quickly

代码语言:javascript
复制
// 4k buffer size.
static final int SIZE = 4 * 1024;
static byte[] buffer = new byte[SIZE];

// Fastest because a FileInputStream has an associated channel.
private static void ScanDataFile(Hunter p, FileInputStream f) throws FileNotFoundException, IOException {
  // Use a mapped and buffered stream for best speed.
  // See: http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly
  FileChannel ch = f.getChannel();
  long red = 0L;
  do {
    long read = Math.min(Integer.MAX_VALUE, ch.size() - red);
    MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, red, read);
    int nGet;
    while (mb.hasRemaining() && p.ok()) {
      nGet = Math.min(mb.remaining(), SIZE);
      mb.get(buffer, 0, nGet);
      for (int i = 0; i < nGet && p.ok(); i++) {
        p.check(buffer[i]);
      }
    }
    red += read;
  } while (red < ch.size() && p.ok());
  // Finish off.
  p.close();
  ch.close();
  f.close();
}
票数 9
EN

Stack Overflow用户

发布于 2012-09-21 22:38:07

我使用的是一个List<ByteBuffer>,其中每个ByteBuffer映射到16MB到1 GB的块中的文件。我使用2的幂来简化逻辑。我已经使用它来映射高达8 TB的文件。

内存映射文件的一个关键限制是您受到虚拟内存的限制。如果你有一个32位的JVM,你将不能映射很多东西。

我不会一直为文件创建新的内存映射,因为这些映射永远不会被清除。您可以创建大量这样的文件,但在某些系统上似乎有大约32K的限制(无论它们有多小)

我发现MemoryMappedFiles有用的主要原因是它们不需要刷新(如果你可以假设操作系统不会死的话),这允许你以低延迟的方式写入数据,而不用担心如果应用程序死了会丢失太多数据,或者因为必须写()或flush()而失去太多的性能。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12531984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档