0

我的代码正在做这样的事情:

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 中运行的。

4

3 回答 3

5

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

于 2010-01-06T19:08:41.407 回答
1

当您尝试保留更多适合内存的对象时,您的内存就会用完。如果您在循环中创建一个对象,它将在超出范围后立即得到 GarbageCollected。

所以如果你写

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

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

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

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

于 2010-01-06T18:38:19.330 回答
0

最有可能的事情是你不小心在某个地方抓住了一些物体。通常的罪魁祸首是实现不佳的缓存或其功能等效项。

另一种可能性是你根本没有足够的内存来做任何事情。Java 以 64 MB 的堆开始(至少 Sun 默认是这样做的)。您可以使用-xmx参数更改它。

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

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

于 2010-01-06T18:40:47.923 回答