1

我正在调试一个我一直在做的相当大的项目(但最初并没有创建),我注意到有时它会以OutOfMemoryError. 该代码正在从文件中加载大量数据,因此一般来说这并不完全令人惊讶。

然而,让我感到困惑的是,我使用 VisualVM 1.3.4 来分析程序,并且它的行为不一致。大多数时候我运行它,堆逐渐扩大到大约 2GB(计算机有 16GB 的 RAM;它用于学术研究),使用的堆在它下面越来越高。大约2GB,它会崩溃。随着时间的推移,该程序不会处理更多信息,因此它不应该在短短几分钟内将堆增加到 2GB。

不过,有时我会在大约 30 秒后突然崩溃,堆大小为 250MB,并且只有大约 100MB 在使用中。java.lang.OutOfMemoryError: Java heap space如果我的堆未满,我将如何获得?

编辑:我正在使用 Eclipse 运行程序,并且我有 VisualVM 插件,因此它会自动启动。另外,我正在使用 Java 7。

4

5 回答 5

2

使用 VM 参数启动应用程序-XX:+HeapDumpOnOutOfMemoryError

分析堆转储并找出导致问题的原因。

Eclipse MAT是找出此类问题的绝佳工具。

于 2012-08-09T13:48:50.120 回答
1

您需要设置 JVM 的最小和最大堆内存

设置 JAVA_OPTS="-Xms128m -Xmx256m"

类似的东西,但具有更大的价值,例如 2G、4G 等等

LE:众所周知,您不能强制 JVM 运行垃圾收集器(即使您可以要求它),但有一些方法可以说服它通过将某些项目的引用设为空来摆脱某些项目。要注意的另一件事是可能延迟初始化的数据库对象。当您尝试创建超出最大堆内存的对象时,可能会出现该错误。

另一个想法可能是一些智力低下的开发人员,由于某些智力迟钝的原因,他们以某种方式以编程方式抛出 OutOfMemoryError。当你到达那部分代码时,这就是你得到的(搜索项目)

于 2012-08-09T14:14:56.127 回答
1

应用程序因 OutOfMemoryError 崩溃可能至少有 2 个原因。

  1. 您的 Java 堆对于它需要处理的数据量来说太小了。然后您可以按照 Matei 的建议增加它,或者按照 Ajay 的建议分析堆转储。

  2. 您的应用程序泄漏内存。这意味着它在处理后会在内存中留下一些不需要的数据。那么从长远来看,增加堆将无济于事。您的选择是堆转储分析(再次)或专门的内存泄漏检测工具,例如Plumbr

于 2012-08-13T14:27:12.230 回答
1

原来崩溃是由使用 OpenJDK JRE 而不是 Oracle 的 JRE 引起的。我不知道 OpenJDK 中究竟是什么错误导致它像这样崩溃,但是更改为 Oracle 的 JRE 最终解决了这个问题。

(我使用 OpenJDK 是因为我在一台 Linux 计算机上,有人在我之前使用它进行开源工作。当我向他提到崩溃时,他认为这可能是原因。他是对的。)

于 2012-08-15T14:16:36.033 回答
1

你有没有大内存支持的 32 位操作系统(win 上的 PAE,linux 上的巨大内存内核......)?如果是,您可能会遇到 32 位系统上每个进程 2GB 内存段的限制。

作为一种变通方法,尝试将 JVM 参数 -Xss192k 设置为每个线程释放 192kb 的堆栈空间,并将参数 -Xmx1024m 设置为使用不超过 1GB 的堆。

于 2013-10-29T10:41:35.180 回答