我正在尝试生成 double 类型的数组,它的大小可以超过 6000 万。此外,我需要迭代生成越来越大的数组(从 20000 开始,迭代我的代码 x 次,连续将我的数组大小扩大 10 或 2 倍,具体取决于迭代中的输出)。在每次迭代 i 结束时,我将大小为 xi 的数组的引用设置为 null,然后将其指向一个新生成的大小为 x(i+1) 的数组,该数组 > xi。但是,我最终在 eclipse 中用完了内存,并出现了通常的 Java 堆空间内存不足错误。我修改了 eclipse.ini 中的 Xmx、Xms 值,但没有成功。在将数组引用设置为 null 后,我还尝试了 System.gc() 建议对 java 进行垃圾回收,但还是没有成功。
我需要这些大数组,因为我正在模拟一个随机过程,在这些数组中收集它的输出(所以我使用一些额外的对象来生成这个数组,这也会占用一些内存)。然后我将这个数组提供给我的主要算法,该算法对其执行一组统计计算。我在生成包含更多观察值的数组时遇到内存不足错误。
无论如何我可以克服这个内存不足的问题吗?将数组的各个元素设置为 null 而不是数组本身有助于释放内存吗?在此先感谢您的任何建议。
最佳答案
- 使用正确的 JRE
您的硬件是 32 位还是 64 位?如果硬件支持 64 位,请确保您使用的是 64 位 JRE。
例如,在 Windows 中,同时安装 32 位 jre 和 64 位 jre 是很常见的。 32 位 JRE 只能寻址大约 1500 MB 的内存。如果切换到 64 位 JRE,您应该能够指定所有可用内存。
- 将 -Xmx 标志传递给您的进程。
您提到了 eclipse.ini - 我假设您是在 Eclipse 中开发软件。 eclipse.ini 配置 Eclipse 使用的内存。您可能想要更改用于从 Eclipse 启动应用程序的运行配置的属性。
- 不要乱用 System.gc()
当您知道有大量垃圾时,没有一个免费的方法可以调用,这令人沮丧。 System.gc() 似乎可以解决您的问题。不要惹它。它可能不会带你去你想去的地方
- 重新思考您的算法
你确定没有办法用很多小数组来实现你想要的吗?有没有办法以分层方式实现相同的结果?有一个单一的整体阵列闻起来像一种反模式。它在内存中保存起来很麻烦,很难调整大小,它给内存管理和垃圾收集带来了压力。即使您将数据结构更改为数组或固定大小的内存页列表,我认为您的情况会更好。
- 内存映射文件。
Java 可以很好地处理内存映射文件。实际数据驻留在磁盘上,但操作系统使它看起来(对于 Java)就像数据在内存中一样。 Java 可以在不使用堆的情况下对这些数据进行操作。文件大小可能非常大(千兆字节),您一次可以映射多个文件。
Peter Lawrey 的 Chronicle 项目利用内存映射文件对海量数据进行高性能访问。这是@peter-lawrey(他在 StackOverflow 上非常活跃,可能很快会在这里发表评论)的一篇博文描述了如何使用内存映射文件来创建 8TB matrix of doubles. 的外观。
关于java - 生成大型 double 组(> 6000 万个对象)时出现 Java OutOfMemory 堆空间错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26511903/