Java:在内存中存储大数据(>;2GB)的官方方式是什么?

Java:在内存中存储大数据(>;2GB)的官方方式是什么?,java,memory,large-data,Java,Memory,Large Data,众所周知的限制是,在字节[]数组中存储数据的常用方法限制为2^31字节(2GB) 有很多Java bug报告和Java规范请求解决了这个问题。其中一些是本世纪初的档案 然而,我发现的所有相关条目均已关闭和/或标记为重复。与此同时,每台消费电脑都有足够的内存,因此这个问题变得越来越重要 因此,我问自己: 处理大型内存数据的官方方法是什么?例如,在RAM中存储4GB 如果没有官方解决方案,社区使用的通用解决方案是什么 注意:我把数据保存到临时文件中,而不是解决方案。内存超过100GB的服务器并不少见

众所周知的限制是,在
字节[]
数组中存储数据的常用方法限制为2^31字节(2GB)

有很多Java bug报告和Java规范请求解决了这个问题。其中一些是本世纪初的档案

然而,我发现的所有相关条目均已关闭和/或标记为重复。与此同时,每台消费电脑都有足够的内存,因此这个问题变得越来越重要

因此,我问自己:

处理大型内存数据的官方方法是什么?例如,在RAM中存储4GB

如果没有官方解决方案,社区使用的通用解决方案是什么


注意:我把数据保存到临时文件中,而不是解决方案。内存超过100GB的服务器并不少见……

没有“官方”方式。在官方Java语言规范中,我从未遇到过关于这个问题的任何东西


但一般来说,您总是可以将如此大的数组表示为数组数组数组,即
byte[][]
。在这种情况下,顶级阵列的每个元素都将描述存储的“页面”。这将允许您在理论上存储2^31x2^31=2^62字节。

没有“官方”方式。在官方Java语言规范中,我从未遇到过关于这个问题的任何东西


但一般来说,您总是可以将如此大的数组表示为数组数组数组,即
byte[][]
。在这种情况下,顶级阵列的每个元素都将描述存储的“页面”。这将允许您在理论上存储2^31x2^31=2^62字节。

Java作为通用语言,目前既没有专门的工具来处理开箱即用的大型内存数据,也没有任何专门的官方建议

使用Java在单个JVM下使用尽可能多的内存时,您有以下选项:

  • 正如本线程中已经提到的,依赖于堆内数组,甚至更好地依赖于那些数组的包装器数组
  • 由于32位索引的限制,请维护一堆堆外的direct,并考虑每个direct的容量。这里也必须提到
  • 使用进程内内存数据库,就像记住自己的数据库一样(H2甚至可以依赖)
  • 使用非进程内存存储,如与相应的
  • 设置(或使用,或类似的东西)并使用内存,就像使用Java中的文件系统一样
每种方法在读/写速度、占用空间、耐久性、可维护性等方面都有各自的缺点和优点。同时,它取决于存储在内存中的对象的性质、其生命周期、访问方案等


因此,必须通过严格匹配特定需求/用例来详细说明所需的选择

Java作为一种通用语言,到目前为止,既没有专门的工具来处理开箱即用的大型内存数据,也没有任何专门的官方建议

使用Java在单个JVM下使用尽可能多的内存时,您有以下选项:

  • 正如本线程中已经提到的,依赖于堆内数组,甚至更好地依赖于那些数组的包装器数组
  • 由于32位索引的限制,请维护一堆堆外的direct,并考虑每个direct的容量。这里也必须提到
  • 使用进程内内存数据库,就像记住自己的数据库一样(H2甚至可以依赖)
  • 使用非进程内存存储,如与相应的
  • 设置(或使用,或类似的东西)并使用内存,就像使用Java中的文件系统一样
每种方法在读/写速度、占用空间、耐久性、可维护性等方面都有各自的缺点和优点。同时,它取决于存储在内存中的对象的性质、其生命周期、访问方案等


因此,必须通过严格匹配特定需求/用例来详细说明所需的选择

由于Andremoniy和Kostiantyn现有的好答案并不是我想要的,所以我对这个话题进行了更深入的研究

我最初想到的是一个Java类的库或代码片段,它在内部处理所有的魔法(例如,将数据分块到多字节数组)。但是,由于一些愚蠢的规定,要求图书馆推荐的问题马上就结束了,我不能在我的问题中这样写

这是我发现的关于现有解决方案的内容的集合:

  • 包名称:it.unimi.dsi.fastutil
  • 许可证:Apache commons
提供具有64位索引的一维数组。它使用多个
字节[]
在内部存储数据。它似乎是为了存储大型数字数组而开发的,因为它提供了对数组中的值进行排序的方法

否定:访问
BigArrays
似乎有点复杂,因为没有对
InputStream
OutputStream
的自适应

elsasticsearch项目包含允许处理大字节(和其他基元)数组的类。 重要类位于包中

缺点是这些类只能作为elasticsearch核心库的一部分使用,elasticsearch核心库相当大,并且还有很多依赖项。 然而,由于它使用Apache2.0许可证,提取和重新打包必要的类似乎是一种合理的方法

笔记 我发现了一个非常有趣的提示,Sun早在2009年就计划为JavaNIO.2提供一个名为
BigByteBuffer
的类。2010年甲骨文收购了Sun,8年后的今天,我们仍然没有BigByteBuffer