32位机器上的Java内存映射

标签 java memory dictionary

我有一个大小为 5 GB 的文件。我喜欢用 Java 对文件进行内存映射。我知道一个内存映射部分不能 > 2 GB。 我的问题是,是否可以创建 5 x 1 gb 内存映射部分来映射完整的 5 gb 文件并在同一个 Java 应用程序中访问它们。

最佳答案

不,这不可能。

这里有两个问题:

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

更复杂的是,2 GB 是理论上的限制,由于内存碎片,在 32 位操作系统上可能无法达到。一些 OS-es 也可能配置了 3-1 内存分割,这只为用户空间程序留下 1 GB 的地址空间,其余的则进入操作系统地址空间。因此,在实践中,您应该尝试映射的 block 应该远小于 2 GB,与映射单个 2 GB block 相比,您更有可能成功映射 4-6 个 250 MB 的 block 。

关于32位机器上的Java内存映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28904498/

相关文章:

JavaFx 应用程序在 IDE 上运行良好,但不能作为 jar 文件运行

java - Vaadin 中的嵌入推文

c - Malloc 更改另一个变量的值 (char*)

c++ - 具有 vector 键的高效 C++ 关联容器

swift - Swift 中的字典

java - 应该使用哪个 SqlDriver 来记录 SQL Server 数据库中的 FIX session 和消息?

java - JAXB Schemagen(v.7.0.450.18): change XmlElement name and XmlType(propOrder={. ..})

matlab - 对于 MATLAB 中的大型稀疏矩阵,计算非零条目的各列的累积和?

memory - 调用 MPI_Init() 后内存会发生什么情况?

python修剪字典列表中的字典