在生成double类型的大型数组(> 6,000,000 obs)时获取Java OutOfMemory堆空间错误

时间:2014-10-22 16:02:35

标签: java arrays eclipse heap

我正在尝试生成double类型的数组,可以达到超过6000万的大小。此外,我需要迭代生成越来越大的数组(从20000开始,遍历我的代码x次数,连续地将我的数组大小膨胀10或2倍,具体取决于迭代中的输出)。在每次迭代i结束时,我将大小为xi的数组的引用设置为null,然后将其指向新生成的大小为x(i + 1)的数组,该数组为>十一。但是,我最终在eclipse中耗尽内存,而通常的Java Heap空间内存不足。我修改了eclipse.ini中的Xmx,Xms值,但没有运气。在将数组引用设置为null之后,我还尝试使用System.gc()来向java建议垃圾收集,再次没有运气。

我需要这些大型数组,因为我正在模拟一个随机进程,在这些数组中收集它的输出(所以我使用了一些额外的对象来生成这个也耗尽了一些内存的数组)。然后我将这个数组提供给我的主算法,该算法对其执行一组统计计算。我在生成具有额外观察次数的阵列时出现内存不足错误。

无论如何我能克服这种内存不足的问题吗?将数组的各个元素设置为null而不是数组本身有助于释放内存吗?提前感谢您的任何建议。

2 个答案:

答案 0 :(得分:4)

  1. 使用正确的JRE
  2. 您的硬件是32位还是64位?如果硬件支持64位,请确保使用的是64位JRE。

    例如,在Windows中,安装32位jre和64位jre是常见的。 32位JRE只能处理大约1500 MB的内存。如果切换到64位JRE,则应该能够指定所有可用内存。

    1. 将-Xmx标记传递给您的进程。
    2. 你提到eclipse.ini - 我假设你正在eclipse中开发你的软件。 eclipse.ini配置Eclipse使用的内存。您可能想要的是更改用于从Eclipse启动应用程序的Run配置的属性。

      1. 不要搞乱System.gc()
      2. 当你知道有大量的垃圾时,没有一个免费的方法来打电话令人沮丧。 System.gc()似乎可以解决您的麻烦。不要惹它。它可能不会让你到达你想去的地方

        1. 重新考虑您的算法
        2. 你确定没有办法通过许多较小的阵列实现你想要的东西吗?有没有办法以分层方式实现相同的结果?有一个单片阵列闻起来像一个反模式。它的麻烦 - 一些留在内存中,很难调整大小,它给内存管理和垃圾收集带来了压力。即使您将数据结构更改为数组或固定大小的内存页列表,我认为您会更好。

          1. 内存映射文件。
          2. Java在内存映射文件中运行良好。实际数据驻留在磁盘上,但操作系统似乎(对Java)数据在内存中。 Java可以在不使用堆的情况下操作此数据。文件大小可能非常大(千兆字节),您可以一次映射多个文件 Peter Lawrey的Chronicle项目利用内存映射文件对大量数据进行高性能访问。这是@ peter-lawrey的博客文章(他在StackOverflow上非常活跃,很可能会在这里发表评论)描述了如何使用内存映射文件来创建8TB matrix of doubles.的外观

答案 1 :(得分:2)

eclipse.ini中的设置仅更改Eclipse本身的设置,它们不会更改您运行的程序的设置。

查看'运行>运行配置'并找到您的Java应用程序',在&#VM; VM参数中设置-Xmx ...值。 '参数'部分标签