main java.lang.OutOfMemoryError:Java堆空间

时间:2010-01-06 18:32:25

标签: java out-of-memory

我的代码是这样做的:

for(SomeObject so : someObjects)
{
  Blah b = so;
  NewObject n = dao.GetNO(b.23);
}

即。它在每次迭代时在for循环中创建一个新变量。

这可能是内存不足问题的原因吗?

Netbeans报告的错误:

Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133)
        at java.lang.StringCoding.decode(StringCoding.java:173)
        at java.lang.String.<init>(String.java:443)
        at java.lang.String.<init>(String.java:515)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:215)
        at com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString(WebResponseImpl.java:205)

Upate 的 这是一个java控制台应用程序,整个应用程序基本上都在forloop中运行。

3 个答案:

答案 0 :(得分:5)

您是使用Java 5或更高版本,还是其中一个旧版JVM?您可以通过使用-XX:+ HeapDumpOnOutOfMemory布防Java命令行或使用JConsole附加到您的进程并请求堆转储来尝试跟踪OOM的原因。然后,您可以使用Eclipse MAT工具打开转储并查看对象图,以查看哪些文件夹在程序中。 MAT可以看到那些主导对象图的对象 - 所以它变得非常清楚究竟什么是泄漏。查看堆栈跟踪没有帮助,并且可能会产生误导,因为程序的某个位置的泄漏可能导致其他位置的分配失败。

答案 1 :(得分:1)

当您尝试保留更多适合内存的对象时,内存不足。如果你在一个循环中创建一个对象,它一旦超出范围就会得到GarbageCollected。

所以,如果你写

for (.....){
   Object o = new Object();
}

- 你永远不会持有o的多个实例,所以它不会成为原因(除非你在其他地方存储对它们的引用,例如将它们放在循环范围之外的地图中)

您需要在代码中寻找更多引用的位置。从你的帖子中我们无法说出更多信息。

顺便说一下,您可能还会考虑使用-Xmx和-Xms选项(在更多信息中键入“java -X”)来增加您在JVM中使用的内存量,这可能会让它运行,尽管它可以运行不会帮你找错。由于您在netbeans中运行,因此它可能正在耗尽内存,因为它在同一个JVM中运行。我不使用netbeans,但你可以检查一下netbeans是否允许你分叉一个新的进程来运行你的程序(这样你就不会试图在与netbeans共享内存时运行,这不小),或者尝试直接在命令行上运行。

答案 2 :(得分:0)

最有可能的是你在某个地方不小心抓住了某些东西。通常的罪魁祸首是执行不当的缓存,或它们的功能等同。

另一种可能性是你根本没有足够的记忆来做你正在做的事情。 Java以64 MB的堆启动(至少Sun默认情况下)。您可以使用-xmx参数更改此内容。

最后,我记得在1.4.X天内,如果有足够的时间(占总进程cpu时间的百分比)花费在垃圾收集上(对于某些特定的垃圾收集器实现),则可能导致OutOfMemoryError。截止值在90%范围内。我在近十年见过这一次,这是一个非常神经质的用例。它可能不是这个,但它可能是。我不确定现代Java中是否存在这种行为。

我的建议:检查dao.GetNO(...)的实现,看看它是否会产生任何副作用,以及它们的生命周期。