java - 生成大型 double 组(> 6000 万个对象)时出现 Java OutOfMemory 堆空间错误

标签 java arrays eclipse heap-memory

我正在尝试生成 double 类型的数组,它的大小可以超过 6000 万。此外,我需要迭代生成越来越大的数组(从 20000 开始,迭代我的代码 x 次,连续将我的数组大小扩大 10 或 2 倍,具体取决于迭代中的输出)。在每次迭代 i 结束时,我将大小为 xi 的数组的引用设置为 null,然后将其指向一个新生成的大小为 x(i+1) 的数组,该数组 > xi。但是,我最终在 eclipse 中用完了内存,并出现了通常的 Java 堆空间内存不足错误。我修改了 eclipse.ini 中的 Xmx、Xms 值,但没有成功。在将数组引用设置为 null 后,我还尝试了 System.gc() 建议对 java 进行垃圾回收,但还是没有成功。

我需要这些大数组,因为我正在模拟一个随机过程,在这些数组中收集它的输出(所以我使用一些额外的对象来生成这个数组,这也会占用一些内存)。然后我将这个数组提供给我的主要算法,该算法对其执行一组统计计算。我在生成包含更多观察值的数组时遇到内存不足错误。

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

最佳答案

  1. 使用正确的 JRE

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

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

  1. 将 -Xmx 标志传递给您的进程。

您提到了 eclipse.ini - 我假设您是在 Eclipse 中开发软件。 eclipse.ini 配置 Eclipse 使用的内存。您可能想要更改用于从 Eclipse 启动应用程序的运行配置的属性。

  1. 不要乱用 System.gc()

当您知道有大量垃圾时,没有一个免费的方法可以调用,这令人沮丧。 System.gc() 似乎可以解决您的问题。不要惹它。它可能不会带你去你想去的地方

  1. 重新思考您的算法

你确定没有办法用很多小数组来实现你想要的吗?有没有办法以分层方式实现相同的结果?有一个单一的整体阵列闻起来像一种反模式。它在内存中保存起来很麻烦,很难调整大小,它给内存管理和垃圾收集带来了压力。即使您将数据结构更改为数组或固定大小的内存页列表,我认为您的情况会更好。

  1. 内存映射文件。

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/

相关文章:

java - 如何将消费者异常作为确认来处理?

arrays - Perl:将数组分配给散列

android - Eclipse - 资源位置

java - 如何使用JAXB作为字符串在JAVA中获取xml文件的一部分

java - (Tomcat 7) 部署的 jar 找不到文件

java - 初始 SessionFactory 创建失败 : java. lang.NoClassDefFoundError: javax/persistence/EntityListeners

java - 如何使用 JNI android 获取应用程序构建配置(调试或发布)?

Java - 您可以从父类(super class)继承并拥有引用基类而不是父类的静态构造函数吗?

arrays - 在 Swift 中反序列化一个以数组作为值的字典

c# - 将数组解包到方法参数中