2010-01-06 112 views
0

我的代码做这样的事情:主要java.lang.OutOfMemoryError:Java堆空间

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

,即它正在创造一个新的变量里面的每个迭代循环。

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

通过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控制台应用程序,以及整个应用程序在for循环运行的基本。

+0

这可能是原因,但不一定是。尝试释放您不再需要的每个对象。特别是,如果您持有不再需要的对象,请检查您的所有集合(地图,列表...)。 – 2010-01-06 18:36:18

+0

您的堆大小设置为? – 2010-01-06 18:37:09

+0

你可以发布一些更实际的代码发生错误吗?有一点需要注意:'com.gargoylesoftware.htmlunit.WebResponseImpl.getContentAsString()'的返回值可能是一个相当大的字符串。 – MatrixFrog 2010-01-06 18:39:30

回答

5

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

+0

考虑到所描述的问题的范围,这似乎是过度杀伤性的。 – 2010-01-06 21:50:59

+0

真的吗?在我看到一个OOM后知道什么对象占用了堆对我来说并不是过分的。 – 2010-01-06 22:08:50

1

当您试图抓住更多适合内存的对象时,内存不足。如果你在一个循环中创建一个对象,只要它超出了范围,就会得到GarbageCollected。

所以,如果你写

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

-you're从未持有邻多个实例,所以它不会是原因(除非你存储参考他们在其他地方,为例如将它们放入循环范围外的映射中)。

您需要在代码中寻找更多引用的地方。从你的帖子中,不可能告诉更多。

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

0

最有可能的是你不小心抓住了某个地方的某些物体。通常的罪魁祸首是执行不当的缓存或功能相当的缓存。

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

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

我的建议:检查dao.GetNO(...)的执行情况,看它是否产生任何物体作为副作用,以及它们的寿命是多少。

相关问题