Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
避免一个“错误”;内存不足错误“;在Java(eclipse)中,何时使用大型数据结构?_Java_Eclipse_Large Data Volumes_Heap Memory_Out Of Memory - Fatal编程技术网

避免一个“错误”;内存不足错误“;在Java(eclipse)中,何时使用大型数据结构?

避免一个“错误”;内存不足错误“;在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个条

好的,我正在写一个程序,不幸的是它需要使用一个巨大的数据结构来完成它的工作,但是它在初始化过程中由于“内存不足错误”而失败。虽然我完全理解这意味着什么以及为什么它是一个问题,但我很难克服它,因为我的程序需要使用这个大型结构,我不知道任何其他存储它的方法

该程序首先对我提供的大量文本文件进行索引。这个很好用

然后它使用这个索引初始化一个大的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。我没有单独运行它,它仍然会给我相同的错误(虽然需要更长的时间才能到达,我想这是一个改进)