我正在调试一个我一直在研究的相当大的项目(但最初没有创建),我注意到有时它会与OutOfMemoryError
崩溃。代码正在从文件中加载大量数据,因此一般来说这并不奇怪。
然而,令我困惑的是,我使用VisualVM 1.3.4来分析程序,并且它的行为不一致。大多数情况下我运行它,堆逐渐扩展到大约2GB(计算机有16GB的RAM;它用于学术研究),使用的堆在它下面越来越高。大约2GB,它会崩溃。随着时间的推移,该程序不会处理更多信息,因此它不应该在几分钟内将堆扩展到2GB。
但是,有时候,我在大约30秒后突然崩溃,堆大小为250MB,使用时只有大约100MB。如果我的堆没有满,我如何获得java.lang.OutOfMemoryError: Java heap space
?
编辑:我正在使用Eclipse来运行程序,我有VisualVM插件,因此它会自动启动。另外,我正在使用Java 7。
答案 0 :(得分:2)
答案 1 :(得分:1)
您需要设置JVM最小和最大堆内存
设置JAVA_OPTS =“ - Xms128m -Xmx256m”
类似的东西,但有更大的价值,如2G,4G无论
LE:众所周知,你不能强迫JVM运行垃圾收集器(即使你可以要求它),但是有一些方法可以说服它通过清空它们的引用去掉一些项目。另一件需要注意的事情是数据库对象可能是惰性初始化的。当您尝试创建超出最大堆内存的对象时,可能会出现该错误。
另一个想法可能是一些迟钝的开发人员,为了一些延迟的原因,以某种方法以编程方式抛出OutOfMemoryError。当你到达那部分代码时,这就是你得到的(搜索项目)
答案 2 :(得分:1)
使用OutOfMemoryError导致应用程序崩溃至少有两个原因。
您的Java堆对于需要处理的数据量来说太小了。然后你可以按建议的Matei增加它,或者将堆转储分析为建议Ajay。
您的应用程序泄漏了内存。这意味着它在处理后会在内存中留下一些不需要的数据。然后,从长远来看,增加堆将无济于事。您的选择是堆转储分析(再次)或专门的内存泄漏检测工具,例如Plumbr
答案 3 :(得分:1)
原因是使用OpenJDK JRE而不是Oracle的JRE导致崩溃。我不确切知道OpenJDK中的错误是什么让它像这样崩溃,但改用Oracle的JRE最终解决了这个问题。
(我使用的是OpenJDK,因为我在一台Linux计算机上,有人在我之前使用开源工作。当我向他提起崩溃时,他认为这可能是原因。他是对的。 )
答案 4 :(得分:1)
你有没有大内存支持的32位操作系统(赢得PAE,linux上的巨大内存......)?如果是,您可能会在32位系统上遇到每个进程2GB内存段限制。
作为解决方法,尝试将JVM参数-Xss192k设置为每个线程配置192kb的堆栈空间,并将参数-Xmx1024m设置为使用不超过1GB的堆。