如果我的堆没有满,我怎么得到“java.lang.OutOfMemoryError:Java堆空间”?

时间:2012-08-09 13:41:48

标签: java memory out-of-memory visualvm

我正在调试一个我一直在研究的相当大的项目(但最初没有创建),我注意到有时它会与OutOfMemoryError崩溃。代码正在从文件中加载大量数据,因此一般来说这并不奇怪。

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

但是,有时候,我在大约30秒后突然崩溃,堆大小为250MB,使用时只有大约100MB。如果我的堆没有满,我如何获得java.lang.OutOfMemoryError: Java heap space

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

5 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

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

设置JAVA_OPTS =“ - Xms128m -Xmx256m”

类似的东西,但有更大的价值,如2G,4G无论

LE:众所周知,你不能强迫JVM运行垃圾收集器(即使你可以要求它),但是有一些方法可以说服它通过清空它们的引用去掉一些项目。另一件需要注意的事情是数据库对象可能是惰性初始化的。当您尝试创建超出最大堆内存的对象时,可能会出现该错误。

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

答案 2 :(得分:1)

使用OutOfMemoryError导致应用程序崩溃至少有两个原因。

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

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

答案 3 :(得分:1)

原因是使用OpenJDK JRE而不是Oracle的JRE导致崩溃。我不确切知道OpenJDK中的错误是什么让它像这样崩溃,但改用Oracle的JRE最终解决了这个问题。

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

答案 4 :(得分:1)

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

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