32位机器上的Java内存映射

时间:2015-03-06 17:40:48

标签: java memory dictionary

我有一个5 gb的文件。我喜欢用Java做内存映射文件。我理解一个内存映射部分不能> 2 gb。 我的问题是,是否有可能创建5 x 1 gb内存映射部分来映射完整的5 gb文件并在同一Java应用程序中访问它们。

2 个答案:

答案 0 :(得分:1)

不,这是不可能的。

这里有两个问题:

  • 首先,32位计算机(或64位计算机上的32位操作系统)只有4 GB(32位)的地址空间,因此您无法映射5 GB的文件同时甚至来自C。
  • 另一个问题是Java通过MappedByteBuffer处理的内存映射实现的限制。即使方法FileChannel.map()需要long的偏移和大小,它也会返回MappedByteBuffer,只能使用int来获取其限制和位置。这意味着即使在64位机器和操作系统上,您可以将整个5 GB文件作为C中的单个区域映射,但在Java中,您必须手动创建一系列映射区域,每个区域不大于2 GB。尽管如此,您至少能够在32位操作系统上映射5 GB的块,而您无法同时映射它们。并且考虑到在Java中取消映射文件区域需要一些丑陋的技巧,因此根据需要映射和取消映射区域以便将它们保持在限制内是不方便的(尽管可能)。您可以查看Lucene或Cassandra的源代码。据我所知,他们还尽可能使用带有本机代码的库,以便以比纯Java允许的更有效的方式处理映射和取消映射。

为了使事情变得更加复杂,2 GB是理论上的限制,由于内存碎片而无法在32位操作系统上访问。某些操作系统也可能配置了3-1内存分割,只留下1 GB的用户空间程序可用的地址空间,其余的则转到OS地址空间。因此,实际上,您应该尝试映射的块应该远小于2 GB,您更有可能成功映射4-6块250 MB的块,而不是映射单个2 GB块。

答案 1 :(得分:0)

请参阅MappedByteBufferFileChannel.map() javadocs。

我不是Java NIO的专家,因此我不确定字节缓冲区是否自动处理块或者是否必须使用多个MappedByteBuffer。您可以随意编写一个简单的类来测试和使用您的大文件。