避免一个“错误”;内存不足错误“;在Java(eclipse)中,何时使用大型数据结构?
好的,我正在写一个程序,不幸的是它需要使用一个巨大的数据结构来完成它的工作,但是它在初始化过程中由于“内存不足错误”而失败。虽然我完全理解这意味着什么以及为什么它是一个问题,但我很难克服它,因为我的程序需要使用这个大型结构,我不知道任何其他存储它的方法 该程序首先对我提供的大量文本文件进行索引。这个很好用 然后它使用这个索引初始化一个大的2D数组。该数组将有n²个条目,其中“n”是文本语料库中唯一单词的数量。对于我正在测试的相对较小的块(大约60个文件),它需要生成大约30000x30000个条目。一旦我在我想要的全部语料库上运行它,它可能会更大 在初始化数据结构(稍后处理)时,它每次索引后都会失败 我所做的事情包括:避免一个“错误”;内存不足错误“;在Java(eclipse)中,何时使用大型数据结构?,java,eclipse,large-data-volumes,heap-memory,out-of-memory,Java,Eclipse,Large Data Volumes,Heap Memory,Out Of Memory,好的,我正在写一个程序,不幸的是它需要使用一个巨大的数据结构来完成它的工作,但是它在初始化过程中由于“内存不足错误”而失败。虽然我完全理解这意味着什么以及为什么它是一个问题,但我很难克服它,因为我的程序需要使用这个大型结构,我不知道任何其他存储它的方法 该程序首先对我提供的大量文本文件进行索引。这个很好用 然后它使用这个索引初始化一个大的2D数组。该数组将有n²个条目,其中“n”是文本语料库中唯一单词的数量。对于我正在测试的相对较小的块(大约60个文件),它需要生成大约30000x30000个条
- 修改我的代码以使用原语
而不是int[]
TreeMap
- 消除冗余结构等李>
- 此外,我已使用
运行该程序,以最大限度地利用分配的内存-Xmx2g
B.如果2D数组中的每个值都不需要完整的32位(整数大小),那么可以使用较小的类型(例如字节)来实现吗?此外,您还应该为它提供尽可能多的堆空间—2GB对于现代系统来说仍然相对较小。RAM很便宜,尤其是当您希望在内存中进行大量处理时。听起来(对数组的用途做一些假设)大多数条目都是0。如果是这样,您可以考虑使用表示形式。
如果您确实有那么多条目(即使假设没有开销,您当前的阵列也在某个地方),那么您将不得不使用某种磁盘存储,或者使用延迟加载/卸载系统。这是处理大型数据集的常见问题。你可以想优化多少就优化多少,但是内存永远都不够(可能),而且一旦数据集再增长一点,你仍然会被烟熏。最具可扩展性的解决方案是只保留较少的内存,处理块,并将结构持久化到磁盘(数据库/文件)上 内存不足问题有几个原因 首先,最简单的情况是需要更多堆。当您的程序可以使用2G正常运行时,您使用的是512M最大堆。将
-Xmx2048m
作为JVM选项进行增加,您就没事了。还要注意的是,64位虚拟机将使用多达32位虚拟机两倍的内存,具体取决于该数据的构成
如果你的问题不是那么简单,那么你可以看看优化。用基本体替换对象等等。这可能是一种选择。根据你的帖子,我真的说不上来
然而,最终你会遇到一个十字路口,你必须在虚拟化和分区之间做出选择
在这种情况下,虚拟化仅仅意味着某种形式的假装内存比实际内存多。操作系统使用虚拟地址空间和硬盘空间作为额外内存。这可能意味着一次只能将部分数据结构保留在内存中,并将其余数据结构持久化到辅助存储(如文件或数据库)
分区是在多个服务器(真实或虚拟)之间分割数据。例如,如果您在纳斯达克跟踪股票交易,您可以在服务器1上输入以“A”开头的股票代码,在服务器2上输入以“B”开头的股票代码,等等。您需要找到一种合理的方法来分割数据,以减少或消除对交叉通信的需求,因为交叉通信限制了您的可扩展性
简单来说,如果您存储的是30K个单词和30K x 30K个单词组合,您可以将其分为四个服务器:
- A-M x A-M
- A-M x N-Z
- N-Z x A-M
- N-Z x N-Z
这只是一个想法。同样,在不知道细节的情况下很难做出评论。+1听起来OP试图创造一种天真的和谐。虽然每个文本可能有30k单词词汇表,但该矩阵中会有大量的零。是的,我想到的是稀疏数组,但如果没有更多关于数据结构意图的细节,就很难进行更多的推测。我喜欢这个声音,我将试一试@msw,你很接近,它类似于concordance(非常天真;)。这是一种不同的统计分析方法,称为超空间模拟语言(HAL)。到目前为止,这对我是有效的。现在我只需要让它运行得更快。正如我在帖子中提到的(我承认这是很少详细的),你已经提到了我已经尝试过的几乎所有东西。后面的解决方案解决了我的问题,但我不想做太复杂的事情(分区听起来超出了我的范围)。请注意,用这些参数启动Eclipse不会有帮助,除非您的代码是Eclipse插件。如果您只是使用Eclipse作为IDE,那么您需要更改应用程序的运行配置,而不是Eclipse的启动。啊,谢谢Joachim。我没有单独运行它,它仍然会给我相同的错误(虽然需要更长的时间才能到达,我想这是一个改进)